OS: Socket API

21st July 2021 at 6:45pm

下面的内容大多数来自 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 的连接。