下面的内容大多数来自 The Linux Programming Interface Chapter 56~61。内容以摘录为主,可能比较零散,不一定会整理。
bind() 和 listen()
One application calls bind() in order to bind the socket to a well-known address, and then calls listen() to notify the kernel of its willingness to accept incoming connections.
Stream Sockets
这段 文字 和 图片 描述了 stream socket 的 client 和 server 的各个阶段、以及如何建立连接。
Server 与 client 交互流程
Server 与 client 交互图
Listen
Server 的 accept 循环
Client 调用 connect()
时,server 可能并没有提前 block 在 accept()
(比如 server 没有上 I/O 多路复用时,正在处理上一个请求)。Server 上的内核会维护一个 未被 accept 的 client 连接队列。这个队列不会无限长,它由 server 调用 listen()
时的 backlog
参数指定。
#include <sys/socket.h>
int listen(int sockfd, int backlog);
如果该 client connect()
时,未 accept 的连接数小于 backlog,则 connect()
会马上成功(在 TCP 场景有些许差异,后面讲);否则 client 会 block 在 connect()
直至 server accept 了一些连接,使得等待 accept 的连接数变小。
<sys/socket.h>
中定义了 SOMAXCONN
变量,表示 backlog 取值的上限;但 Linux 也支持修改此参数(通过 sysctl -w net.core.somaxconn
或者修改 /proc/sys/net/core/somaxconn
文件)。
Accept
Server 调用 accept()
后,会返回一个 socket fd 表示 client 的连接。