ESTAB 状态下的 Recv-Q Send-Q 分别表示内核协议栈的发送缓冲区和接受缓冲区中保存的内容字节数。
在 Linux 上,TCP 的三次握手在内核里完成。内核通过一个半连接和已连接 2 个队列来实现。
已连接队列的大小由 net.core.somaxconn 和 int listen(int sockfd, int backlog) 传入的 backlog 较小值来决定。对于 LISTEN 状态的 Send-Q 表示的就是这个队列的大小。
默认的内核参数 net.core.somaxconn 通常都是 12
root@ubuntu:~# sysctl -a | grep somaxconn net.core.somaxconn = 128
理解TCP握手过程中建连接的流程和队列
SYN_REVD, ESTABELLISHED 状态对应的队列
TCP 建立连接时要经过 3 次握手,在客户端向服务器发起连接时,
对于服务器而言,一个完整的连接建立过程,服务器会经历 2 种 TCP 状态:SYN_REVD, ESTABELLISHED。
对应也会维护两个队列:
- 一个存放 SYN_REVD状态的连接 队列(半连接队列)
- 一个存放ESTABLISHED状态但是还未被accept的连接队列。
如上图所示,这里有两个队列:syns queue(半连接队列);accept queue(全连接队列)
三次握手中,server收到client的syn后,把相关信息放到半连接队列中,同时回复syn+ack给client,比如syn floods 攻击就是发生在这个阶段(下文会有详细介绍和Demo)。server收到client的ack,如果这时全连接队列没满,那么从半连接队列拿出相关信息放入到全连接队列中,否则按tcp_abort_on_overflow指示的执行。
这时如果全连接队列满了并且tcp_abort_on_overflow是0的话,server过一段时间再次发送syn+ack给client(也就是重新走握手的第二步),如果client超时等待比较短,就很容易异常了。
server
# -*- coding: UTF-8 -*- import socket # 建立一个服务端 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('10.10.16.82',6999)) server.listen(3) while True: pass # conn,addr = server.accept() # print(conn,addr)
root@ubuntu:~# sysctl net.ipv4.tcp_abort_on_overflow net.ipv4.tcp_abort_on_overflow = 1 root@ubuntu:~#
client
# -*- coding: UTF-8 -*- import socket import time client_lists = [] for i in range(5): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) client.connect(("10.10.16.82", 6999)) client_lists.append(client) time.sleep(600)
root@ubuntu:~# tcpdump -i enahisic2i0 tcp and host 10.10.16.82 and port 6999 -nv tcpdump: listening on enahisic2i0, link-type EN10MB (Ethernet), capture size 262144 bytes 16:49:55.921965 IP (tos 0x0, ttl 64, id 44278, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47852 > 10.10.16.82.6999: Flags [S], cksum 0x31db (correct), seq 2098854357, win 29200, options [mss 1460,sackOK,TS val 1726200647 ecr 0,nop,wscale 7], length 0 16:49:55.922049 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.47852: Flags [S.], cksum 0x34e5 (incorrect -> 0xe130), seq 54435121, ack 2098854358, win 65160, options [mss 1460,sackOK,TS val 3435288302 ecr 1726200647,nop,wscale 7], length 0 16:49:55.922136 IP (tos 0x0, ttl 64, id 44279, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.47852 > 10.10.16.82.6999: Flags [.], cksum 0x0da1 (correct), ack 1, win 229, options [nop,nop,TS val 1726200647 ecr 3435288302], length 0 16:49:55.922186 IP (tos 0x0, ttl 64, id 23888, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47854 > 10.10.16.82.6999: Flags [S], cksum 0xfcb8 (correct), seq 2744911987, win 29200, options [mss 1460,sackOK,TS val 1726200647 ecr 0,nop,wscale 7], length 0 16:49:55.922205 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.47854: Flags [S.], cksum 0x34e5 (incorrect -> 0xe438), seq 1706033812, ack 2744911988, win 65160, options [mss 1460,sackOK,TS val 3435288303 ecr 1726200647,nop,wscale 7], length 0 16:49:55.922285 IP (tos 0x0, ttl 64, id 23889, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.47854 > 10.10.16.82.6999: Flags [.], cksum 0x10a9 (correct), ack 1, win 229, options [nop,nop,TS val 1726200647 ecr 3435288303], length 0 16:49:55.923023 IP (tos 0x0, ttl 64, id 52066, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47856 > 10.10.16.82.6999: Flags [S], cksum 0x2f50 (correct), seq 3677658689, win 29200, options [mss 1460,sackOK,TS val 1726200647 ecr 0,nop,wscale 7], length 0 16:49:55.923108 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.47856: Flags [S.], cksum 0x34e5 (incorrect -> 0x1240), seq 1484330075, ack 3677658690, win 65160, options [mss 1460,sackOK,TS val 3435288303 ecr 1726200647,nop,wscale 7], length 0 16:49:55.923176 IP (tos 0x0, ttl 64, id 52067, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.47856 > 10.10.16.82.6999: Flags [.], cksum 0x3eaf (correct), ack 1, win 229, options [nop,nop,TS val 1726200648 ecr 3435288303], length 0 16:49:55.923260 IP (tos 0x0, ttl 64, id 8776, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47858 > 10.10.16.82.6999: Flags [S], cksum 0xcf21 (correct), seq 1647736683, win 29200, options [mss 1460,sackOK,TS val 1726200648 ecr 0,nop,wscale 7], length 0 16:49:55.923279 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.47858: Flags [S.], cksum 0x34e5 (incorrect -> 0x8410), seq 1390233591, ack 1647736684, win 65160, options [mss 1460,sackOK,TS val 3435288304 ecr 1726200648,nop,wscale 7], length 0 16:49:55.923346 IP (tos 0x0, ttl 64, id 8777, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.47858 > 10.10.16.82.6999: Flags [.], cksum 0xb080 (correct), ack 1, win 229, options [nop,nop,TS val 1726200648 ecr 3435288304], length 0 16:49:55.923447 IP (tos 0x0, ttl 64, id 59229, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x0fd6 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726200648 ecr 0,nop,wscale 7], length 0 16:49:56.928741 IP (tos 0x0, ttl 64, id 59230, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x0be9 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726201653 ecr 0,nop,wscale 7], length 0 16:49:59.008741 IP (tos 0x0, ttl 64, id 59231, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x03c9 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726203733 ecr 0,nop,wscale 7], length 0 16:50:03.088750 IP (tos 0x0, ttl 64, id 59232, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0xf3d8 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726207813 ecr 0,nop,wscale 7], length 0 16:50:11.568748 IP (tos 0x0, ttl 64, id 59233, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0xd2b8 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726216293 ecr 0,nop,wscale 7], length 0 16:50:28.208747 IP (tos 0x0, ttl 64, id 59234, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x91b8 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726232933 ecr 0,nop,wscale 7], length 0 16:51:00.848743 IP (tos 0x0, ttl 64, id 59235, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x1238 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726265573 ecr 0,nop,wscale 7], length 0 16:52:06.221982 IP (tos 0x0, ttl 64, id 8778, offset 0, flags [DF], proto TCP (6), length 52)
root@ubuntu:~# tcpdump -i enahisic2i0 tcp and host 10.10.16.82 and port 6999 -nv tcpdump: listening on enahisic2i0, link-type EN10MB (Ethernet), capture size 262144 bytes 16:49:55.921965 IP (tos 0x0, ttl 64, id 44278, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47852 > 10.10.16.82.6999: Flags [S], cksum 0x31db (correct), seq 2098854357, win 29200, options [mss 1460,sackOK,TS val 1726200647 ecr 0,nop,wscale 7], length 0 16:49:55.922049 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.47852: Flags [S.], cksum 0x34e5 (incorrect -> 0xe130), seq 54435121, ack 2098854358, win 65160, options [mss 1460,sackOK,TS val 3435288302 ecr 1726200647,nop,wscale 7], length 0 16:49:55.922136 IP (tos 0x0, ttl 64, id 44279, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.47852 > 10.10.16.82.6999: Flags [.], cksum 0x0da1 (correct), ack 1, win 229, options [nop,nop,TS val 1726200647 ecr 3435288302], length 0 16:49:55.922186 IP (tos 0x0, ttl 64, id 23888, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47854 > 10.10.16.82.6999: Flags [S], cksum 0xfcb8 (correct), seq 2744911987, win 29200, options [mss 1460,sackOK,TS val 1726200647 ecr 0,nop,wscale 7], length 0 16:49:55.922205 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.47854: Flags [S.], cksum 0x34e5 (incorrect -> 0xe438), seq 1706033812, ack 2744911988, win 65160, options [mss 1460,sackOK,TS val 3435288303 ecr 1726200647,nop,wscale 7], length 0 16:49:55.922285 IP (tos 0x0, ttl 64, id 23889, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.47854 > 10.10.16.82.6999: Flags [.], cksum 0x10a9 (correct), ack 1, win 229, options [nop,nop,TS val 1726200647 ecr 3435288303], length 0 16:49:55.923023 IP (tos 0x0, ttl 64, id 52066, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47856 > 10.10.16.82.6999: Flags [S], cksum 0x2f50 (correct), seq 3677658689, win 29200, options [mss 1460,sackOK,TS val 1726200647 ecr 0,nop,wscale 7], length 0 16:49:55.923108 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.47856: Flags [S.], cksum 0x34e5 (incorrect -> 0x1240), seq 1484330075, ack 3677658690, win 65160, options [mss 1460,sackOK,TS val 3435288303 ecr 1726200647,nop,wscale 7], length 0 16:49:55.923176 IP (tos 0x0, ttl 64, id 52067, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.47856 > 10.10.16.82.6999: Flags [.], cksum 0x3eaf (correct), ack 1, win 229, options [nop,nop,TS val 1726200648 ecr 3435288303], length 0 16:49:55.923260 IP (tos 0x0, ttl 64, id 8776, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47858 > 10.10.16.82.6999: Flags [S], cksum 0xcf21 (correct), seq 1647736683, win 29200, options [mss 1460,sackOK,TS val 1726200648 ecr 0,nop,wscale 7], length 0 16:49:55.923279 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.47858: Flags [S.], cksum 0x34e5 (incorrect -> 0x8410), seq 1390233591, ack 1647736684, win 65160, options [mss 1460,sackOK,TS val 3435288304 ecr 1726200648,nop,wscale 7], length 0 16:49:55.923346 IP (tos 0x0, ttl 64, id 8777, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.47858 > 10.10.16.82.6999: Flags [.], cksum 0xb080 (correct), ack 1, win 229, options [nop,nop,TS val 1726200648 ecr 3435288304], length 0 16:49:55.923447 IP (tos 0x0, ttl 64, id 59229, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x0fd6 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726200648 ecr 0,nop,wscale 7], length 0 16:49:56.928741 IP (tos 0x0, ttl 64, id 59230, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x0be9 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726201653 ecr 0,nop,wscale 7], length 0 16:49:59.008741 IP (tos 0x0, ttl 64, id 59231, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x03c9 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726203733 ecr 0,nop,wscale 7], length 0 16:50:03.088750 IP (tos 0x0, ttl 64, id 59232, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0xf3d8 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726207813 ecr 0,nop,wscale 7], length 0 16:50:11.568748 IP (tos 0x0, ttl 64, id 59233, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0xd2b8 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726216293 ecr 0,nop,wscale 7], length 0 16:50:28.208747 IP (tos 0x0, ttl 64, id 59234, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x91b8 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726232933 ecr 0,nop,wscale 7], length 0 16:51:00.848743 IP (tos 0x0, ttl 64, id 59235, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.47860 > 10.10.16.82.6999: Flags [S], cksum 0x1238 (correct), seq 3865883262, win 29200, options [mss 1460,sackOK,TS val 1726265573 ecr 0,nop,wscale 7], length 0 16:52:06.221982 IP (tos 0x0, ttl 64, id 8778, offset 0, flags [DF], proto TCP (6), length 52)
root@ubuntu:~# netstat -pan | grep 6999 tcp 0 0 10.10.16.82:6999 0.0.0.0:* LISTEN 45809/python3 tcp 0 0 10.10.16.82:6999 10.10.16.81:47756 ESTABLISHED 45809/python3 root@ubuntu:~# netstat -pan | grep 6999 tcp 4 0 10.10.16.82:6999 0.0.0.0:* LISTEN 47824/python3 tcp 0 0 10.10.16.82:6999 10.10.16.81:47858 ESTABLISHED - tcp 0 0 10.10.16.82:6999 10.10.16.81:47854 ESTABLISHED - tcp 0 0 10.10.16.82:6999 10.10.16.81:47856 ESTABLISHED - tcp 0 0 10.10.16.82:6999 10.10.16.81:47852 ESTABLISHED - root@ubuntu:~# ss -tl | grep 6999 LISTEN 4 3 10.10.16.82:6999 0.0.0.0:* root@ubuntu:~# ss -tl | grep 6999 LISTEN 4 3 10.10.16.82:6999 0.0.0.0:* root@ubuntu:~# netstat -pan | grep 6999 tcp 4 0 10.10.16.82:6999 0.0.0.0:* LISTEN 47824/python3 tcp 0 0 10.10.16.82:6999 10.10.16.81:47858 ESTABLISHED - tcp 0 0 10.10.16.82:6999 10.10.16.81:47854 ESTABLISHED - tcp 0 0 10.10.16.82:6999 10.10.16.81:47856 ESTABLISHED - tcp 0 0 10.10.16.82:6999 10.10.16.81:47852 ESTABLISHED -
[root@bogon ~]# python conn.py Traceback (most recent call last): File "conn.py", line 7, in <module> client.connect(("10.10.16.82", 6999)) File "/usr/lib64/python2.7/socket.py", line 224, in meth return getattr(self._sock,name)(*args) socket.error: [Errno 110] Connection timed out
客户端没收到rst,重传几次之后timeout
怎么监控半连接满了
667399 SYNs to LISTEN sockets ignored表明已经忽略SYN次了,此时说明半连接队列满了,或者因为全连接满而影响了半连接的进行
root@ubuntu:~# netstat -s | egrep "listen|LISTEN" 12 times the listen queue of a socket overflowed 12 SYNs to LISTEN sockets dropped root@ubroot@ubuntu:~# netstat -s | egrep "listen|LISTEN" 12 times the listen queue of a socket overflowed 12 SYNs to LISTEN sockets dropped root@ubuntu:~# untu:~#
总结
- 当 client 通过 connect 向 server 发出 SYN 包时,client 会维护一个 socket 等待队列,而 server 会维护一个 SYN 队列
- 此时进入半链接的状态,如果 socket 等待队列满了,server 则会丢弃,而 client 也会由此返回 connection time out;只要是 client 没有收到 SYN+ACK,3s 之后,client 会再次发送,如果依然没有收到,9s 之后会继续发送
- 半连接 syn 队列的长度为 max(64, /proc/sys/net/ipv4/tcp_max_syn_backlog) 决定
- 当 server 收到 client 的 SYN 包后,会返回 SYN, ACK 的包加以确认,client 的 TCP 协议栈会唤醒 socket 等待队列,发出 connect 调用
- client 返回 ACK 的包后,server 会进入一个新的叫 accept 的队列,该队列的长度为 min(backlog, somaxconn),默认情况下,somaxconn 的值为 128,表示最多有 129 的 ESTAB 的连接等待 accept(),而 backlog 的值则由 int listen(int sockfd, int backlog) 中的第二个参数指定,listen 里面的 backlog 的含义请看这里。需要注意的是,一些 Linux 的发型版本可能存在对 somaxcon 错误 truncating 方式。
- 当 accept 队列满了之后,即使 client 继续向 server 发送 ACK 的包,也会不被相应,此时,server 通过 /proc/sys/net/ipv4/tcp_abort_on_overflow 来决定如何返回,0 表示直接丢丢弃该 ACK,1 表示发送 RST 通知 client;相应的,client 则会分别返回 read timeout 或者 connection reset by peer。上面说的只是些理论,如果服务器不及时的调用 accept(),当 queue 满了之后,服务器并不会按照理论所述,不再对 SYN 进行应答,返回 ETIMEDOUT。根据这篇文档的描述,实际情况并非如此,服务器会随机的忽略收到的 SYN,建立起来的连接数可以无限的增加,只不过客户端会遇到延时以及超时的情况。
可以看到,整个 TCP stack 有如下的两个 queue:
1. 一个是 half open(syn queue) queue(max(tcp_max_syn_backlog, 64)),用来保存 SYN_SENT 以及 SYN_RECV 的信息。
2. 另外一个是 accept queue(min(somaxconn, backlog)),保存 ESTAB 的状态,但是调用 accept()。
注意,之前我对 Recv-Q/Send-Q 的理解有些误差,使用 ss 获取到的 Recv-Q/Send-Q 在 LISTEN 状态以及非 LISTEN 状态所表达的含义是不同的。从 tcp_diag.c 源码中可以看到二者的区别:
LISTEN 状态: Recv-Q 表示的当前等待服务端调用 accept 完成三次握手的 listen backlog 数值,也就是说,当客户端通过 connect() 去连接正在 listen() 的服务端时,这些连接会一直处于这个 queue 里面直到被服务端 accept();Send-Q 表示的则是最大的 listen backlog 数值,这就就是上面提到的 min(backlog, somaxconn) 的值。
其余状态: 非 LISTEN 状态之前理解的没有问题。Recv-Q 表示 receive queue 中的 bytes 数量;Send-Q 表示 send queue 中的 bytes 数值
demo1
server
# -*- coding: UTF-8 -*- import socket # 建立一个服务端 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('10.10.16.82',6999)) server.listen(3) for num in range(1,4): conn,addr = server.accept() print(conn,addr) while True: pass # conn,addr = server.accept() # print(conn,addr)
client
[root@bogon ~]# cat conn.py # -*- coding: UTF-8 -*- import socket import time client_lists = [] for i in range(8): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) client.connect(("10.10.16.82", 6999)) client_lists.append(client) time.sleep(600)
demo1
# -*- coding: UTF-8 -*- import socket # 建立一个服务端 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('localhost',6999)) #绑定要监听的端口 server.listen(5) while True:# conn就是客户端链接过来而在服务端为期生成的一个链接实例 conn,addr = server.accept() #等待链接,多个链接的时候就会出现问题,其实返回了两个值 print(conn,addr) while True: try: data = conn.recv(1024) #接收数据 print('recive:',data.decode()) #打印接收到的数据 conn.send(data.upper()) #然后再发送数据 except ConnectionResetError as e: print('关闭了正在占线的链接!') break conn.close()
root@ubuntu:~/cloudflare-blog/2019-09-tcp-keepalives# ss -tl | grep 6999 LISTEN 0 5 127.0.0.1:6999 0.0.0.0:* root@ubuntu:~/cloudflare-blog/2019-09-tcp-keepalives#
demo2
# -*- coding: UTF-8 -*- import socket # 建立一个服务端 server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('localhost',6999)) #绑定要监听的端口 server.listen(125) while True:# conn就是客户端链接过来而在服务端为期生成的一个链接实例 conn,addr = server.accept() #等待链接,多个链接的时候就会出现问题,其实返回了两个值 print(conn,addr) while True: try: data = conn.recv(1024) #接收数据 print('recive:',data.decode()) #打印接收到的数据 conn.send(data.upper()) #然后再发送数据 except ConnectionResetError as e: print('关闭了正在占线的链接!') break conn.close()
root@ubuntu:~/cloudflare-blog/2019-09-tcp-keepalives# ss -tl | grep 6999 LISTEN 0 125 127.0.0.1:6999 0.0.0.0:* root@ubuntu:~/cloudflare-blog/2019-09-tcp-keepalives#
demo3
root@ubuntu:~/c++# sysctl net.ipv4.tcp_abort_on_overflow net.ipv4.tcp_abort_on_overflow = 0 root@ubuntu:~/c++#
tcp_abort_on_overflow 为0表示如果三次握手第三步的时候全连接队列满了那么server扔掉client 发过来的ack(在server端认为连接还没建立起来)
# -*- coding: UTF-8 -*- import socket server = socket.socket(socket.AF_INET,socket.SOCK_STREAM) server.bind(('10.10.16.82',6999)) server.listen(3) while True:# conn,addr = server.accept() print(conn,addr) while True: try: data = conn.recv(1024) #卡住 except ConnectionResetError as e: print('reset') break conn.close()
root@ubuntu:~/c++# ss -lnt | grep 6999 LISTEN 4 3 10.10.16.82:6999 0.0.0.0:*
客户端发起5个连接,只有一个accept
root@ubuntu:~/c++# tcpdump -i enahisic2i0 tcp and port 6999 -env tcpdump: listening on enahisic2i0, link-type EN10MB (Ethernet), capture size 262144 bytes 15:54:18.914303 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 15737, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.59488 > 10.10.16.82.6999: Flags [S], cksum 0x441c (correct), seq 640899815, win 29200, options [mss 1460,sackOK,TS val 1636464320 ecr 0,nop,wscale 7], length 0 15:54:18.914382 48:57:02:64:e7:ab > 48:57:02:64:ea:1b, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.59488: Flags [S.], cksum 0x34e5 (incorrect -> 0x9d3c), seq 1546774267, ack 640899816, win 65160, options [mss 1460,sackOK,TS val 3345551295 ecr 1636464320,nop,wscale 7], length 0 15:54:18.914459 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 15738, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.59488 > 10.10.16.82.6999: Flags [.], cksum 0xc9ac (correct), ack 1, win 229, options [nop,nop,TS val 1636464320 ecr 3345551295], length 0 15:54:18.914549 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 39816, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.59490 > 10.10.16.82.6999: Flags [S], cksum 0x72c8 (correct), seq 1448475670, win 29200, options [mss 1460,sackOK,TS val 1636464320 ecr 0,nop,wscale 7], length 0 15:54:18.914569 48:57:02:64:e7:ab > 48:57:02:64:ea:1b, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.59490: Flags [S.], cksum 0x34e5 (incorrect -> 0x7637), seq 1013668979, ack 1448475671, win 65160, options [mss 1460,sackOK,TS val 3345551295 ecr 1636464320,nop,wscale 7], length 0 15:54:18.914639 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 39817, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.59490 > 10.10.16.82.6999: Flags [.], cksum 0xa2a7 (correct), ack 1, win 229, options [nop,nop,TS val 1636464320 ecr 3345551295], length 0 15:54:18.914722 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 18029, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.59492 > 10.10.16.82.6999: Flags [S], cksum 0x71b6 (correct), seq 831070707, win 29200, options [mss 1460,sackOK,TS val 1636464320 ecr 0,nop,wscale 7], length 0 15:54:18.914746 48:57:02:64:e7:ab > 48:57:02:64:ea:1b, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.59492: Flags [S.], cksum 0x34e5 (incorrect -> 0xc897), seq 1070007717, ack 831070708, win 65160, options [mss 1460,sackOK,TS val 3345551295 ecr 1636464320,nop,wscale 7], length 0 15:54:18.914810 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 18030, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.59492 > 10.10.16.82.6999: Flags [.], cksum 0xf507 (correct), ack 1, win 229, options [nop,nop,TS val 1636464320 ecr 3345551295], length 0 15:54:18.914888 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 49588, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.59494 > 10.10.16.82.6999: Flags [S], cksum 0xf4a6 (correct), seq 710911530, win 29200, options [mss 1460,sackOK,TS val 1636464320 ecr 0,nop,wscale 7], length 0 15:54:18.914910 48:57:02:64:e7:ab > 48:57:02:64:ea:1b, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.59494: Flags [S.], cksum 0x34e5 (incorrect -> 0x527f), seq 62864054, ack 710911531, win 65160, options [mss 1460,sackOK,TS val 3345551295 ecr 1636464320,nop,wscale 7], length 0 15:54:18.914996 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 49589, offset 0, flags [DF], proto TCP (6), length 52) 10.10.16.81.59494 > 10.10.16.82.6999: Flags [.], cksum 0x7eef (correct), ack 1, win 229, options [nop,nop,TS val 1636464320 ecr 3345551295], length 0 15:54:18.915173 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 55297, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.81.59496 > 10.10.16.82.6999: Flags [S], cksum 0x6808 (correct), seq 2642788255, win 29200, options [mss 1460,sackOK,TS val 1636464321 ecr 0,nop,wscale 7], length 0 15:54:18.915194 48:57:02:64:e7:ab > 48:57:02:64:ea:1b, ethertype IPv4 (0x0800), length 74: (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60) 10.10.16.82.6999 > 10.10.16.81.59496: Flags [S.], cksum 0x34e5 (incorrect -> 0xf43a), seq 967693932, ack 2642788256, win 65160, options [mss 1460,sackOK,TS val 3345551296 ecr 1636464321,nop,wscale 7], length 0 15:54:18.915256 48:57:02:64:ea:1b > 48:57:02:64:e7:ab, ethertype IPv4 (0x0800), length 66: (tos 0x0, ttl 64, id 55298, offset 0, flags [DF], proto TCP (6), length 52)
客户端发起5个连接
# -*- coding: UTF-8 -*- import socket import time client_lists = [] for i in range(5): client = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) client.connect(("10.10.16.82", 6999)) client_lists.append(client) time.sleep(600)