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)){
    //        // 已经准备就绪 做一些该做的操作
    //    }
    // ...
}