TCP 三次握手原理,你真的理解吗?
tcp_abort_on_overflow
为0表示如果三次握手第三步的时候全连接队列满了
那么server扔掉client 发过来的ack
(在server端认为连接还没建立起来
);1表示第三步的时候如果全连接队列满了,server发送一个reset包给client
,表示废掉这个握手过程和这个连接(本来在server端这个连接就还没建立起来)。
cat /proc/sys/net/ipv4/tcp_abort_on_overflow
0
- TCP三次握手后有个accept全连接队列,进到这个队列才能从Listen变成accept,backlog这个值控制全连接队列的大小,默认backlog 值是50,很容易就满了。满了之后握手第三步的时候server就忽略了client发过来的ack包(
tcp_abort_on_overflow
值为0时)(隔一段时间server重发握手第二步的syn+ack包给client,重发多少次由/proc/sys/net/ipv4/tcp_synack_retries
决定),如果这个连接一直排不上队就异常了。
$ cat /proc/sys/net/ipv4/tcp_synack_retries
5
- 如何判断全连接队列满了
netstat -s |egrep "listen|LISTEN"
,如果有overflow信息且过一段时间就增加的话,说明全连接队列满了。ss -lnt
: 三列表示全连接队列最大多少,第二列表示全连接队列当前使用了多少(这个还未验证)
$ ss -lnt
State Recv-Q Send-Q Local Address:Port Peer Address:Port
LISTEN 0 128 *:25000 *:*
LISTEN 0 128 *:22 *:*
LISTEN 0 128 :::22 :::*
- tcp三次握手图解
tcp-sync-queue-and-accept-queue-small
可以看到,accept在三次握手完成之后,SYN后连接被加入sync queue(半连接队列),server收到ACK后连接被加入accept queue(全连接队列)中。
- sync queue大小由
/proc/sys/net/ipv4/tcp_max_syn_backlog
决定
- sync queue大小由
$ cat /proc/sys/net/ipv4/tcp_max_syn_backlog
128
- accept queue大小由
min(backlog,/proc/sys/net/core/somaxconn)
决定
$ cat /proc/sys/net/core/somaxconn
128
TCP listen() Backlog
- 三次握手是干了啥
The connection is established
when sequence numbers have been exchanged and synchronized in both directions
. The sequence numbers are used to provide reliable transmission and flow control .the connection is initiated by a listening socket receivinga segment containing a synchronize control flag (SYN) and a sequence number. The server side acknowledges this and sends its own sequence number (SYN|ACK). The client then acknowledges this sequence number (ACK)
.
- backlog参数有可能会被系统静静的改小。
The backlog parameter is silently truncated to SOMAXCONN in /usr/src/linux/net/ipv4/af_inet.c. SOMAXCONN is defined as 128 in /usr/src/linux/socket.h for 2.x kernels.