qscool 2020-05-10
#include <fcntl.h> int flag = 0; // 获取到当前的设置 flag = fcntl(sockfd,F_SETFL,0); flag |=O_NONBLOCK; // 设置回去 fcntl(sockfd,F_SETFL,flag);
或者使用 ioctl()函数
#include <sys/ioctl.h> int b_on = 1; ioctl(sockfd, FIONBIO, &b_on);
#include <sys/select.h> int fd_num = -1; // 一般使用一个计数器计算集合中的文件描述符数量 void FD_ZERO(fd_set *fdset); // 将集合清零 void FD_SET(int fd, fd_set *fdset); // 将关心的文件描述符加入到集合中 void FD_CLR(int fd, fd_set *fdset); // 将某个文件描述符从集合中清除 int FD_ISSET(int fd, fd_set *fdset); // 判断fd是否在set集合中 int select(int nfds, fd_set *restrict readfds, fd_set *restrict writefds, fd_set *restrict errorfds, struct timeval *restrict timeout); // nfds 传入 fd_num+1 表示最大集合数 // 这三个集合如果需要传入 不需要则可以传NULL // readfds 读集合 // writefds 写集合 // errorfds 异常集合 // timeout 超时等待 // struct timeval /* _STRUCT_TIMEVAL { __darwin_time_t tv_sec; /* seconds */ 秒 __darwin_suseconds_t tv_usec; /* and microseconds */ 毫秒 }; */
Demo:多路复用模型
#include <sys/select.h> #include <stdio.h> int main(int argc, char *argv[]) { fd_set rset; // 创建读集合 int max = -1; int fd = -1; // 句柄 struct timeval timeout; // socket 连接省略... // bind 省略... // listen 省略... // 如果循环是要一直执行如下操作 FD_ZERO(&rset); // 将集合清零 FD_SET(fd, &rset); // 将创建好的fd加入到读集合中 max++; // 计数器+1 // 依次将其他连接的fd加入... 省略 // 设置超时时间 为5s timeout.tv_sec = 5; timeout.tv_usec = 0; // 使用select监控 select(max + 1, &rset, NULL, NULL, &timeout); // 依次判断select监控后的rset // 例如:fd // 现在的rset集合中存放的是已经就绪的描述符 所以需要依次判断 手上的描述符是否存在于集合中 if (FD_ISSET(fd, &rset)) { // 已经准备就绪 做一些该做的操作 } // if (FD_ISSET(fd2,&rset)){ // // 已经准备就绪 做一些该做的操作 // } // ... }