- 一、参数介绍
- 二、代码实现
- 1.服务器端
- 2.客户端
一、参数介绍
#include二、代码实现 1.服务器端#include #include int select(int nfds,fd_set* readfds,fd_set* writefds,fd_set* exceptfds,struct timeval* timeout); -参数: nfds:指定被监听文件的文件描述符的总数。通常被设置为select监听的所有文件描述符中的最大值加1,因为文件描述符是从1开始计数的。 readfds:可读文件描述符的集合 writefds:可写文件描述符的集合 exceptfds:异常事件文件描述符的集合 timeout:用来设置select函数的超时时间。 struct timeval{ long tv_sec; long tv_usec; } -NULL 则select将一直阻塞,直到某个文件描述符就绪 -tv_sec = 0 tv_usec = 0, 不阻塞 -tv_sec > 0 tc_usec > 0, 阻塞对应的时间 -返回值: - -1:失败 - >0(n):检测的集合中有n个文件描述符发生了变化 - 0:超时时间内没有任何文件描述符就绪 void FD_ZERO(FD_SET* fdset);//fd_set一共有1024bit,全部初始化为0 void FD_SET(int fd,fd_set* fdset);//将参数文件描述符fd 对应的标志位,设置为1 void FD_CLR(int fd,fd_set* fdset); //将参数文件描述符fd对应的标志位设置为0 int FD_ISSET(int fd,fd_set* fdset);//判断fd对应的标志位是0还是1,返回值:fd对应的标志位的值,0,返回0,1,返回1
代码如下(示例):
#include2.客户端#include #include #include #include #include int main() { //创建socket int lfd = socket(PF_INET, SOCK_STREAM, 0); struct sockaddr_in saddr; saddr.sin_port = htons(9999); saddr.sin_family=AF_INET; saddr.sin_addr.s_addr = INADDR_ANY; //绑定 bind(lfd, (struct sockaddr *)&saddr, sizeof(saddr)); //监听 listen(lfd, 5); //创建一个fd_set集合,存放的是需要检测的文件描述符 fd_set rdset,tmp; FD_ZERO(&rdset); FD_SET(lfd, &rdset); int maxfd = lfd; while(1) { tmp = rdset; //调用select系统函数,让内核帮检测那些文件描述符有数据 int ret = select(maxfd + 1, &tmp, NULL, NULL, NULL); if(ret == -1) { perror("select"); exit(0); }else if(ret == 0) { continue; }else if(ret>0) { //说明检测到了有文件描述符的对应的缓冲区的数据发生了改变 if(FD_ISSET(lfd,&tmp)) {//表示有新的客户端连接进来了 struct sockaddr_in caddr; int len = sizeof(caddr); int cfd = accept(lfd, (struct sockaddr *)&caddr, &len); //将新的文件描述符加入到集合中 FD_SET(cfd, &rdset); maxfd = maxfd > cfd ? maxfd : cfd; } for (int i = lfd + 1; i <= maxfd; i++) { if(FD_ISSET(i,&tmp)) {//说明这个文件描述符对应的客户端发来了数据 char buf[1024] = {0}; int len = read(i, buf, sizeof(buf)); if(len==-1) { perror("read"); }else if(len==0) { printf("client closed...n"); close(i); FD_CLR(i, &rdset); }else if(len>0) { printf("read buf=%sn", buf); write(i, buf, strlen(buf) + 1); } } } } } close(lfd); return 0; }
代码如下(示例):
#include#include #include #include #include int main() { //1.创建套接字 int fd = socket(AF_INET, SOCK_STREAM, 0); if(fd==-1) { perror("socket"); exit(-1); } //2.连接服务器 struct sockaddr_in saddr; inet_pton(AF_INET, "182.61.11.197", &saddr.sin_addr.s_addr); saddr.sin_family = AF_INET; saddr.sin_port = htons(9999); //连接服务器 int ret = connect(fd, (struct sockaddr *)&saddr, sizeof(saddr)); if(ret==-1) { perror("connet"); exit(-1); } //3.通信 char recvbuf[1024] = {0}; int i = 0; int num = 0; while (1) { char sendbuf[1024] = {0}; sprintf(sendbuf, "send data %d", num++); write(fd, sendbuf, strlen(sendbuf) + 1); //接收 int len = read(fd, sendbuf, sizeof(sendbuf)); if(len==-1) { perror("read"); return -1; }else if(len>0) { printf("read buf = %sn", sendbuf); }else{ printf("服务器已经断开连接...n"); break; } usleep(1000); } //关闭连接 close(fd); return 0; }



