首先,我们知道,socket() 调用创建指定系列和指定类型的套接字。
s = socket(family, type, protocol);
socket将返回套接字句柄。套接字句柄即为文件描述符s,而一般情况下文件描述符默认都是阻塞的。为了满足某些时候的需要,我们使用fcntl函数来对其进行非阻塞的设置。
函数原型
1 |
|
传入的cmd的值不同,后面追加的参数也不相同。
fctnl函数有五种功能:
- 复制一个现有的文件描述符(cmd = F_DUPFD)
- 获得/设置文件描述符标记(cmd = FGETFD或FSETFD)
- 获得/设置文件状态标记(cmd = FGETFL或FSETFL)
- 获得/设置异步I/O所有权(cmd = FGETOWN 或 FSETOWN)
- 获得/设置记录锁(cmd = FGETLK,FSETLK或F_SETLKW)
我们此处只是用第三种功能,获得/设置文件状态标记,就可以将一个文件描述符设置为非阻塞。
实现函数SetNoBlock
基于fcntl,我们实现一个SetNoBlock函数,将文件描述符设置为非阻塞
1 | void SetNoBlock(int fd) |
- 使用F_GETFL将当前的文件描述符的属性取出来(这是一个位图)
- 然后再使用FSETFL将文件描述符设置回去。设置回去的同时,加上一个O_NONBLOCK参数
轮询方式读取标准输入
1 |
|