设置非阻塞套接字
int fcntl(int fd, int cmd,...);
位于头文件:<fcntl.h>
返回值:若成功则返回值取决于cmd,失败则返回-1.
使用fcntl开启非阻塞模式io的代码:
注:assert仅为了方便,可以替换为其他release模式下也检测的代码。
int flags = fcntl(fd, F_GETFL, 0);
assert(flags >= 0)
flags |= O_NONBLOCK;
assert(fcntl(fd, F_SETFL, flags) >= 0);
POSIX规定fcntl函数执行各种描述符控制操作。
套接字选项
使用getsockopt函数和setsockopt函数获取和设置套接字选项,这里不准备详细介绍,原因如下:首先这一块的内容很多很杂,没必要强行记忆,用的时候查询即可,其次这部分代码属于例行公事,变化很小。下面简要说明几个常用的套接字选项:
SO_KEEPALIVE
传输层的心跳包,时间间隔为2个小时,一般在应用层设置间隔更短的心跳包。
SO_LINGER
详见close函数,这个套接字选项可以设置close函数的执行逻辑,默认的close函数会尝试尽量将发送缓冲区的内容发送给对端并触发正常关闭,本选项可以设置在固定时间之后丢弃发送缓冲区中的内容并发送RST分节。
SO_RCVBUF和SO_SNDBUF
设置套接字接收缓冲区和发送缓冲区的大小
SO_RCVLOWAT和SO_SNDLOWAT
设置接收低水位标记和发送低水位标记
SO_REUSEADDR和SO_REUSEPORT
这里介绍SO_REUSEADDR的一种用法:允许启动监听服务器并绑定端口port,即使port作为本地端口的连接仍然存在。
TCP_NODELAY
禁止tcp协议的nagle算法,nagle算法的目的是减少小分组在广域网上的数目。如果某个连接上有待确认数据,那么发送小分组的行为就不会发生。
非阻塞io
阻塞io的逻辑:
读:如果有数据可读就返回读到的数据,可以小于请求读取的数据,如果没有数据可读则阻塞。
写:能够全部写入则写入并返回,否则阻塞至有空间写入本次全部数据。
非阻塞io逻辑:
读:有数据则返回读到的数据,没有数据可读则返回EWOULDBLOCK错误。
写:如果缓冲区根本没有空间则返回EWOULDBLCK错误,否则写入缓冲区能够容纳的字节数,这个值可以小于请求写入的字节数。
对非阻塞的监听套接字调用accept函数,没有新连接到达则返回EWOULDBLOCK错误。
对非阻塞的套接字调用connect函数,如果连接不能立即建立则返回EINPROGRESS错误
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。