思维导图:
使用selsect实现TCP客户端的并发
代码
#include<a.h>
#define SER_PORT 8888 //服务器端口号
#define SER_IP "192.168.125.50" //服务器ip地址
#define CLI_PORT 6666 //客户端的端口号
#define CLI_IP "192.168.125.50" //客户端ip地址int main(int argc, const char *argv[])
{//1、创建用于通信的套接字文件描述符int cfd = -1;cfd = socket(AF_INET, SOCK_STREAM, 0);if(cfd == -1){perror("socket error");return -1;}printf("cfd = %d\n", cfd); //3//2、绑定(可选)//2.1 填充地址信息结构体 struct sockaddr_in cin;cin.sin_family = AF_INET;cin.sin_port = htons(CLI_PORT);cin.sin_addr.s_addr = inet_addr(CLI_IP);//2.2绑定if(bind(cfd, (struct sockaddr*)&cin, sizeof(cin)) == -1){perror("bind error");return -1;}printf("bind success\n");//3、连接服务器//3.1 填充服务器地址信息结构体struct sockaddr_in sin;sin.sin_family = AF_INET;sin.sin_port = htons(SER_PORT);sin.sin_addr.s_addr = inet_addr(SER_IP);//3.2 连接if(connect(cfd, (struct sockaddr*)&sin, sizeof(sin)) == -1){perror("connect error");return -1;}printf("连接成功\n");//准备一个文件描述器fd_set readfds,tempfds;//临时集合//清空容器FD_ZERO(&readfds);//将要检测的文件放入集合中FD_SET(0,&readfds);FD_SET(cfd,&readfds);int res=-1; //接收select函数对容器的中文件描述符号检测的返回值//4、收发数据char wbuf[128]=""; //终端char rbuf[128]=""; //接收服务器发来的消息while(1){tempfds=readfds; //存储一份数据//使用select函数对容器中的文件描述符进行检测res=select(cfd+1,&tempfds,NULL,NULL,NULL);if(res==-1){perror("select error");return -1;}else if(res==0){printf("timeout\n");return -1;}//判断终端是否发生事件if(FD_ISSET(0,&tempfds)){//清空数组bzero(wbuf, sizeof(wbuf));printf("请输入>>>");fgets(wbuf, sizeof(wbuf), stdin); //从终端输入数据wbuf[strlen(wbuf)-1] = 0; //将换行改为'\0'//发送给服务器send(cfd, wbuf, sizeof(wbuf), 0);printf("发送成功\n");if(strcmp(wbuf, "quit") == 0){break;}}//判断是否是服务器发来的消息触发if(FD_ISSET(cfd,&tempfds)){//清空数组bzero(rbuf,sizeof(rbuf));//接收服务器发来的消息recv(cfd, rbuf, sizeof(rbuf), 0);printf("[%s:%d]:%s\n", SER_IP, SER_PORT, rbuf);}}//5、关闭套接字close(cfd);return 0;
}