3. listen()
用于监听套接字上的连接
3.1 包含头文件
#include <sys/types.h>
#include <sys/socket.h>
3.2 函数主体
int listen(int sockfd, int backlog);
参数解释:
- int sockfd
listen() 将 sockfd 引用的套接字标记为被动套接字,即用作使用 accept()接受传入连接请求的套接字。 这里的sockfd 引用SOCK_STREAM 或 SOCK_SEQPACKET 类型的套接字。 - int backlog
backlog 参数定义了 sockfd 的挂起连接队列可能增长到的最大长度。如果连接请求在队列已满时到达,则客户端可能会收到指示 ECONNREFUSED 的错误。如果基础协议支持重新传输,则可能会忽略该请求,以便以后的重新尝试连接成功。
如果 backlog 参数大于 /proc/sys/net/core/somaxconn 中的值,则它将被静默截断为该值;此文件中的默认值为 128,可以按需要自己修改。
这里针对第二个参数进行补充说明:
当一个主动套接字(即没有listen()的套接字)调用listen()变为被动套接字时,系统会为该socket维护两个队列,第一个队列是已经建立连接(即完成三次握手建立连接)的套接字,第二个队列是为建立完整连接的套接字(即正在完成三次握手),Linux 2.2以后,第二个参数表示等待接受(accept)的完全建立的(即第一个队列)套接字的队列长度,且队列长度为backlog+1。记住这里的两个队列,之后accept()、connect()函数中会详细提及。
3.3 返回值
成功返回0;错误返回-1,错误类型如下:
错误类型 | 解释 |
---|---|
EADDRINUSE | 另一个套接字已在同一端口上监听 |
EADDRINUSE | 引用的套接字还未绑定到具体的地址,或者尝试绑定到临时端口时,这些端口都已经在使用中 |
EBADF | sockfd 不是有效的文件描述符 |
ENOTSOCK | 文件描述符 sockfd 未引用套接字。 |
EOPNOTSUPP | 套接字不是支持 listen() 操作的类型。 |
3.4 结束
listen()函数较为简单,但是是流套接字服务端必要步骤。关于socket背后的TCP通信原理,之后会在其他专栏更新。
最后,还是建议所有函数都进行返回值判断,以提高代码的健壮性。