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