一、TCP函数
1、socket()
分配fd和空的TCP控制块(TCP control block)
2、bind()
把ip和端口绑定到TCB上
1、listen
listen()函数的第二个参数backlog是网络编程中一个关键但常被误解的概念。它的含义和实现随着操作系统(尤其是 Linux 内核)的发展而有所演变。以下是其发展历程和核心要点:
1.早期定义(Linux 2.2 之前)
backlog被理解为总的连接队列长度上限,包括:- 半连接队列(SYN 队列):处于
SYN_RCVD状态、尚未完成三次握手的连接。 - 全连接队列(Accept 队列):已完成三次握手、等待应用程序调用
accept()的连接。
- 半连接队列(SYN 队列):处于
- 此时,
backlog控制的是这两个队列的总和。
2.Linux 2.2 及以后的变化
从 Linux 内核 2.2 开始,两个队列被分离管理:
backlog参数仅控制全连接队列(Accept 队列)的最大长度。
此外,实际生效的backlog值还会受到系统全局限制的影响:
- 实际队列长度 =
min(backlog, /proc/sys/net/core/somaxconn) - 默认
somaxconn通常为 128(现代系统可能更高,如 4096)。
3.现代行为总结(如 Linux 5.x+)
listen(sockfd, backlog)中的backlog只影响已完成连接队列(ESTABLISHED)的容量。- 半连接队列由内核自动管理,受
tcp_max_syn_backlog和 SYN Cookie 机制调控。 - 如果 Accept 队列满,新的完成连接可能会被丢弃或触发重传,影响性能甚至导致连接失败。
4.实践建议
- 在高并发服务器(如 Nginx、Redis)中,通常会显式设置较大的
backlog(如 511、4096),并调整somaxconn。 - 示例(Nginx 配置):
listen 80 backlog=65535; - 应用层需及时调用
accept(),避免 Accept 队列堆积