TCPselect
代码
服务器
#define IP "192.168.0.104" //IP地址
int jp(fd_set tempfds,int maxfd)
char buf[128] = ""; //用来接收数据
char buf1[128] = ""; //用来接收数据
int snfd = -1; //用来接受从终端的文件描述符
bzero(buf,sizeof(buf)); //清空字符串
int res = scanf("%d %s",&snfd,buf); //从终端读取文件描述符和接收数据
while(getchar() != 10); //循环吸收垃圾字符
if(res != 2) //判断是否输入了两个数据
if(snfd <= 2 || FD_ISSET(snfd,&tempfds) == 0) //判断是否正确输入文件描述符
printf("输入非法文件描述符:%d\n",snfd);
sprintf(buf1,"%c%c%s",'s',':',buf);
if(send(snfd,buf1,sizeof(buf1),0) < 0) //判断是否发送成功
int lj(int sfd,struct sockaddr_in sevecin[1024],fd_set *preadfds,int *maxfd)
struct sockaddr_in cin; //客户端信息结构体
socklen_t len = sizeof(cin); //信息结构体真实大小
newfd = accept(sfd,(struct sockaddr *)&cin,&len);
printf("[%s : %d] 客户端连接成功!\n",inet_ntoa(cin.sin_addr),ntohs(cin.sin_port));
sevecin[newfd] = cin; //将新的客户端连接到客户端数组中
FD_SET(newfd,preadfds);//将新的文件描述符添加到读集合中
*maxfd = *maxfd > newfd ? *maxfd : newfd;//更新最大文件描述符
int jh(int fd, struct sockaddr_in sevecin[1024],fd_set *readfds,int *maxfd)
char buf[128] = ""; //搬运工
bzero(buf,sizeof(buf)); //清空字符串
ssize_t res = recv(fd,buf,sizeof(buf),0);
printf("[%s : %d]客户端已下线!\n",inet_ntoa(sevecin[fd].sin_addr),ntohs(sevecin[fd].sin_port));
FD_CLR(fd,readfds);//从读集合中删除该信息
while(FD_ISSET(*maxfd,readfds) && (*maxfd)-- >= 0);//更新最大文件描述符
printf("[%s : %d]: %s\n",inet_ntoa(sevecin[fd].sin_addr),\
ntohs(sevecin[fd].sin_port),buf);
if(send(fd,buf,sizeof(buf),0) < 0)
int main(int argc, const char *argv[])
if((sfd = socket(AF_INET,SOCK_STREAM,0)) < 0)//判断是否创建成功
if(setsockopt(sfd,SOL_SOCKET,SO_REUSEADDR,&reuse,sizeof(reuse)) < 0)
sin.sin_family = AF_INET;
sin.sin_port = htons(PORT); //端口号
sin.sin_addr.s_addr = inet_addr(IP); //IP
if(bind(sfd, (struct sockaddr *)&sin,sizeof(sin)) < 0)//判断是否绑定成功
if(listen(sfd,128) < 0)//判断是否设置监听成功
struct sockaddr_in sevecin[1024];
bzero(sevecin,sizeof(sevecin)); //清空数组
s_res = select(maxfd+1,&tempfds,NULL,NULL,NULL); //多路复用
for(int i = 0; i <= maxfd; i++)
if(FD_ISSET(i,&tempfds) == 0)
lj(sfd,sevecin,&readfds,&maxfd);
jh(i,sevecin,&readfds,&maxfd);

客户端
#define IP "192.168.0.104" //IP
int main(int argc, const char *argv[])
int cfd = socket(AF_INET,SOCK_STREAM,0);
cin.sin_family = AF_INET;
cin.sin_port = htons(PORT); //端口
cin.sin_addr.s_addr = inet_addr(IP); //IP
if(connect(cfd,(struct sockaddr *)&cin,sizeof(cin)) < 0)
FD_ZERO(&readfds); //清空集合
FD_SET(0,&readfds); //加入集合
char buf[128] = ""; //定义搬运工
int s_res = select(cfd+1,&tempfds,NULL,NULL,NULL);
bzero(buf,sizeof(buf));//清空字符串
fgets(buf,sizeof(buf),stdin); //从终端获取数据
buf[strlen(buf) - 1] = 0; //换行变成'\0'
if(send(cfd,buf,sizeof(buf),0) < 0) //发送数据并判断数据是否发送成功
if(FD_ISSET(cfd,&tempfds))
bzero(buf,sizeof(buf)); //清空字符串
int res = recv(cfd,buf,sizeof(buf),0);
else if(res == 0) //判断服务器是否下线
if(close(cfd)) //关闭文件描述符并判断是否关闭成功

现象
