tcp状态机
2020-01-14 本文已影响0人
紫色红色黑色
概念
RTT:round trip time,客户端与服务端之间的往返时间
通告窗口:advertised window,告知对端在任何时刻它一次能从对端接收多少字节的数据,从而确保发送端发送的数据不会使接受端缓冲区溢出。
MSS:maximum segment size,连接中每个TCP分节中可以接受的最大数据量
MSL:maximum segment lifetime,最长分节生命周期
连接和断开
1.三次握手(three-way handshake)
- 服务端准备好接受外来连接。称为被动打开(passive open)
- 客户端发起主动打开(active open)。发送一个SYN分节,告知服务端该连接中自己发送的数据的初始序列号
- 服务端确认(ACK)客户端SYN,同时发送一个SYN分节,告知客户端该连接中自己发送的数据的初始序列号
- 客户端确认(ACK)服务端的SYN
2.四次挥手
- 一端调用close,执行主动关闭(active close)。该端发送一个FIN字节,表示数据发送完毕
- 接收这个FIN的对端执行被动关闭(passive close)。确认这个FIN。
- 一段时间后,接收FIN的一端也调用close。也发送一个FIN字节
- 接收这个最终FIN的原发送端(执行主动关闭的一端)确认这个FIN
注意:
- FIN、SYN对应的ACK就是原序列号+1
- 在步骤2和步骤3之间,从执行被动关闭一端到执行主动关闭一端流动数据时可能的,称为半关闭(half-close)
3.状态机
state transition diagram
实例
tcp连接的分组交换服务端对客户请求的确认是伴随其应答发出的,这种做法称为捎带(piggybacking),它通常在服务端处理请求并产生应答的时间小于200ms时发生。如果服务端耗用更长时间,将会出现先是确认后是应答。
4.TIME_WAIT
执行主动关闭的一端经历这个状态,持续时间是2MSL。
存在理由
- 可靠地实现TCP全双工连接的终止
如果主动关闭一端发送的最终ACK丢失,可以重传该ACK。 - 允许老的重复分节在网络中消逝
假设ip1:port1和ip2:port2之间建立了TCP连接,该连接关闭后一段时间又在同ip:port上建立了TCP连接。后一个连接称为前一个连接的化身(incarnation)。TCP为了防止某个连接的老的重复分组在该连接终止后再现,从而误解为属于同一个连接的某个新的化身。TCP将不给处于TIME_WAIT状态的连接发起新的化身。TIME_WAIT的持续时间为2MSL,足够让老的重复分组被丢弃。
5.工具
tcpdump抓包参考tcpdump/wireshark 抓包及分析。
- docker安装centos
# 拉取image到本地
docker pull centos:7
# 以image构建容器
docker run -d --name centos7 centos:7 -sleep 3600d
# 进入容器
docker exec -it centos7 bash
# 进入容器后安装必须软件
yum install net-tools
yum install wget
yum install tcpdump
- tcpdump分析
开两个窗口
# 一个窗口发起http请求
wget http://example.com
# 另一个窗口抓包
tcpdump -n -S -i eth0 host example.com
显示
[root@afd5a8e9ff36 /]# tcpdump -n -S -i eth0 host example.com
tcpdump: verbose output suppressed, use -v or -vv for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
# 三次握手
15:12:29.164793 IP 172.17.0.2.53836 > 93.184.216.34.http: Flags [S], seq 15566632, win 29200, options [mss 1460,sackOK,TS val 128735 ecr 0,nop,wscale 7], length 0
15:12:29.518988 IP 93.184.216.34.http > 172.17.0.2.53836: Flags [S.], seq 452882384, ack 15566633, win 65535, options [mss 1460,wscale 2,eol], length 0
15:12:29.519107 IP 172.17.0.2.53836 > 93.184.216.34.http: Flags [.], ack 452882385, win 229, length 0
# 传送数据
15:12:29.519440 IP 172.17.0.2.53836 > 93.184.216.34.http: Flags [P.], seq 15566633:15566742, ack 452882385, win 229, length 109: HTTP: GET / HTTP/1.1
15:12:29.520037 IP 93.184.216.34.http > 172.17.0.2.53836: Flags [.], ack 15566742, win 65535, length 0
15:12:29.827035 IP 93.184.216.34.http > 172.17.0.2.53836: Flags [P.], seq 452882385:452883845, ack 15566742, win 65535, length 1460: HTTP: HTTP/1.1 200 OK
15:12:29.827055 IP 172.17.0.2.53836 > 93.184.216.34.http: Flags [.], ack 452883845, win 251, length 0
15:12:29.827091 IP 93.184.216.34.http > 172.17.0.2.53836: Flags [P.], seq 452883845:452883963, ack 15566742, win 65535, length 118: HTTP
15:12:29.827101 IP 172.17.0.2.53836 > 93.184.216.34.http: Flags [.], ack 452883963, win 251, length 0
# 四次挥手
15:12:29.827874 IP 172.17.0.2.53836 > 93.184.216.34.http: Flags [F.], seq 15566742, ack 452883963, win 251, length 0
15:12:29.828203 IP 93.184.216.34.http > 172.17.0.2.53836: Flags [.], ack 15566743, win 65535, length 0
15:12:30.074756 IP 93.184.216.34.http > 172.17.0.2.53836: Flags [F.], seq 452883963, ack 15566743, win 65535, length 0
15:12:30.074806 IP 172.17.0.2.53836 > 93.184.216.34.http: Flags [.], ack 452883964, win 251, length 0
# 导出到文件
tcpdump -n -S -i eth0 host example -w example.pcap
# 读入文件
tcpdump -r example.pcap
- ss使用
socket statistics,属于iproute中的工具。netstat属于net-tools中的工具。net-tools和iproute对比。
yum install iproute iproute-doc
net-tools和iproute2对别
引用
https://meik2333.com/posts/tcp-connection/
https://linoxide.com/linux-command/use-ip-command-linux