📄 tcp_select_svr.c
字号:
#include <stdio.h>
#include <stdlib.h>
#include <os_defs.h>
#if __OS_TYPE__ == __OS_LINUX__
#include <signal.h>
#endif
#include <os_socket.h>
/*
服务器采用select来实现多路复用,只使用一个进程来完成所有处理
软件开销较少
*/
void usage()
{
printf("tcp_select_svr port\n");
}
#define MAXSOCKFD 20
int main(int argc ,char * argv[])
{
int port;
OS_SOCKET new_fd,socket = INVALID_SOCKET;
char msg[ ] ="Welcome to server!";
/* 联接表,以socket fd 为下标,如果对应位为1,
表示这一下对应socket是联接上*/
int is_connected[MAXSOCKFD];
char buffer[512];
int fd,addr_len,len;
struct sockaddr_in addr;
fd_set readfds;
if(argc<2)
{
usage();
exit(-1);
}
#if __OS_TYPE__ == __OS_LINUX__
/* 防止用户下线时,内核发送SIGPIPE消息,此消息默认把进程退出,因此突略这一信号*/
signal(SIGPIPE,SIG_IGN);
#endif
port = atoi(argv[1]);
if((port <= 1024 ) || (port >65000))
{
fprintf(stderr,"error port %s\n",argv[1]);
exit(-2);
}
/* 清空所有联接*/
for(fd=0;fd<MAXSOCKFD;fd++)
is_connected[fd]=0;
OS_SocketInit();
if(OS_OpenTCPServer(&socket, port)!=OS_OK)
{
fprintf(stderr,"create tcp file server failure on %d\n",port);
exit(-3);
}
printf("server waiting on port %d,listen socket =%d\n",port,socket);
while(1)
{
FD_ZERO(&readfds);
FD_SET(socket,&readfds);
for(fd=0;fd<MAXSOCKFD;fd++)
if(is_connected[fd]) FD_SET(fd,&readfds);
if(select(MAXSOCKFD,&readfds,NULL,NULL,NULL)<0)
continue;
/* 检查是哪一些socket收到包*/
for(fd=3;fd<MAXSOCKFD;fd++)
{
if(!FD_ISSET(fd,&readfds))
continue;
if(fd == socket )
{/* 是侦听socket,这意味着有客户申请联接*/
if((new_fd = accept (socket,(struct sockaddr *)&addr,(socklen_t*)&addr_len))!=SOCKET_ERROR)
{
/* 发送欢迎信息*/
send(new_fd,msg,sizeof(msg),0);
/* 登记这一客户端*/
is_connected[new_fd] =1;
printf("---client socket=%d (ip=%s:port=%d) connected\n",new_fd,inet_ntoa(addr.sin_addr),ntohs(addr.sin_port));
}
}
else
{ /* 普通客户端发来的聊天信息*/
if((len =recv(fd,buffer,sizeof(buffer),0))<0)
{ /* 用户下线*/
is_connected[fd]=0;
OS_SocketClose(fd);
}
else
{
int wfd;
/* 把信息转发*/
for(wfd = 3;wfd<MAXSOCKFD;wfd++)
{
if((wfd == socket) || (is_connected[wfd] == 0) || (wfd == fd))
continue;
if(send(wfd,buffer,len,0) == SOCKET_ERROR)
{
is_connected[wfd]=0;
OS_SocketClose(wfd);
}
}
}
}
}
}
OS_SocketClose(socket);
OS_SocketClear();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -