TCP全连接队列

一、半连接队列和全连接队列

TCP三次握手时,Linux内核会维护两个队列:

半连接队列,被称为SYN队列
全连接队列,被称为 accept 队列

a.客户端发送SYN包,并进入SYN_SENT状态
b.服务端接收到数据包将相关信息放入半连接队列(SYN 队列),并返回SYC+ACK包给客户端
c.服务端接收客户端ACK数据包,这时如果全连接队列(accept 队列)没满,就会从半连接队列里面将数据取出来放入全连接队列,等待应用使用,当队列已满就会跟据/proc/sys/net/ipv4/tcp_abort_on_overflow配置执行策略。

二、全连接队列查看

netstat -tunap

全连接队列的大小
全连接队列的大小为 min(backlog, somaxconn)+1,默认情况下 somaxconn 的值为 128(可以通过cat /proc/sys/net/core/somaxconn 查看),
表示最多有129个ESTABLISHED连接等待服务端 accept,而 backlog 的值则由 int listen(int sockfd, int backlog) 中的第二个参数指定

LISTEN 状态下数据:
# Recv-Q 表示完成三次握手并等待服务端 accept 的TCP全连接数
# Send-Q 表示全连接队列的大小(备注: netstat下Send-Q不会显示)

非LISTEN 状态下数据:
# Recv-Q 已收到但未被应用进程读取的字节数
# Send-Q 已发送但未收到确认的字节数

三、全连接队列溢出

当有大量请求进入,如果TCP全连接队列过小的话就会出现全连接队列溢出,当出现全连接队列溢出现象的时候,后续的请求就会被丢弃,就会出现服务请求数量上不去的现象。
当全连接队列已满就会根据tcp_abort_on_overflow策略进行处理。Linux 可通过 /proc/sys/net/ipv4/tcp_abort_on_overflow 进行配置。

    当tcp_abort_on_overflow=0,服务accept队列满了,客户端发来ack,服务端直接丢弃该ACK,此时服务端处于 SYN_RCVD 的状态,
客户端处于 ESTABLISHED 状态。在该状态下会有一个定时器重传服务端 SYN/ACK 给客户端(不超过 /proc/sys/net/ipv4/tcp_synack_retries 指定的次数,Linux下默认5)。
超过后,服务器不在重传,后续也不会有任何动作。如果此时客户端发送数据过来,服务端会返回 RST。

    当tcp_abort_on_overflow=1,服务端accept队列满了,客户端发来ack,服务端直接返回RST通知client,
表示废掉这个握手过程和这个连接,client会报connection reset by peer。

 

posted on 2025-04-07 10:08  寒魔影  阅读(21)  评论(0)    收藏  举报

导航