这里主要分析研究四次挥手的发起方问题
1.概述
具体的准备环境参考这里:
arthurchiao.art/blog/tcpdum… (tcpdump/wireshark 抓包及分析(2019)
这里使用curl命令发起请求,做两组测试:
curl -v -H "Connection: close" http://example.com
curl -v -H http://example.com (curl默认保持keep-alive)
抓包命令:
tcpdump -i eth0 host example.com
这里也可生成抓包文件,供后续导入wireshark之列的分析工具使用:
tcpdump -i eth0 host example.com -w example.pcap
2 客户端被动关闭
curl -v -H "Connection: close" example.com 对应执行结果:
06:19:43.555914 IP f6a3e2309201.40164 > a96-7-128-175.deploy.static.akamaitechnologies.com.80: Flags [S], seq 626339111, win 64240, options [mss 1460,sackOK,TS val 1062722354 ecr 0,nop,wscale 7], length 0
06:19:43.836440 IP a96-7-128-175.deploy.static.akamaitechnologies.com.80 > f6a3e2309201.40164: Flags [S.], seq 815745127, ack 626339112, win 64240, options [mss 1460], length 0
06:19:43.836560 IP f6a3e2309201.40164 > a96-7-128-175.deploy.static.akamaitechnologies.com.80: Flags [.], ack 1, win 64240, length 0
06:19:43.836994 IP f6a3e2309201.40164 > a96-7-128-175.deploy.static.akamaitechnologies.com.80: Flags [P.], seq 1:95, ack 1, win 64240, length 94: HTTP: GET / HTTP/1.1
06:19:43.837550 IP a96-7-128-175.deploy.static.akamaitechnologies.com.80 > f6a3e2309201.40164: Flags [.], ack 95, win 64240, length 0
#这里看到服务端主动发起了fin关闭连接,客户端收到fin 状态会变为CLOSE_WAIT (注意这里使发送数据同时发送fin 【FP.】)
06:19:44.221804 IP a96-7-128-175.deploy.static.akamaitechnologies.com.80 > f6a3e2309201.40164: Flags [FP.], seq 1:1522, ack 95, win 64240, length 1521: HTTP: HTTP/1.1 200 OK
06:19:44.221999 IP f6a3e2309201.40164 > a96-7-128-175.deploy.static.akamaitechnologies.com.80: Flags [.], ack 1523, win 62718, length 0
# 这里客户端关闭处理完毕,发送fin 给服务端,客户端状态变成last_ack
06:19:44.222197 IP f6a3e2309201.40164 > a96-7-128-175.deploy.static.akamaitechnologies.com.80: Flags [F.], seq 95, ack 1523, win 62718, length 0
# 这里客户端收到服务端发过来的最后一次 ack ,边关闭连接,状态变为close
06:19:44.222907 IP a96-7-128-175.deploy.static.akamaitechnologies.com.80 > f6a3e2309201.40164: Flags [.], ack 96, win 64239, length 0
从客户端抓包来看,整个过程即为短暂,客户端netsatn -a 几乎无法抓到socket连接状态变化过程
客户端被动关闭时状态变化 :
CONNECTED ->
收到服务端Fin -> CLOSE_WAIT ->
向服务端发送fin对应的ack -> 发送客户端fin -> LAST_ACK ->
收到服务端对于客户端fin的ack -> CLOSE
但是关闭过程极其短暂,不容易在netstat 时监测
3 客户端主动关闭
curl -v example.com 对应执行结果:
06:28:08.548185 IP f6a3e2309201.43978 > a96-7-128-198.deploy.static.akamaitechnologies.com.80: Flags [S], seq 3094484268, win 64240, options [mss 1460,sackOK,TS val 1272087523 ecr 0,nop,wscale 7], length 0
06:28:08.916888 IP a96-7-128-198.deploy.static.akamaitechnologies.com.80 > f6a3e2309201.43978: Flags [S.], seq 290066441, ack 3094484269, win 64240, options [mss 1460], length 0
06:28:08.917112 IP f6a3e2309201.43978 > a96-7-128-198.deploy.static.akamaitechnologies.com.80: Flags [.], ack 1, win 64240, length 0
06:28:08.917901 IP f6a3e2309201.43978 > a96-7-128-198.deploy.static.akamaitechnologies.com.80: Flags [P.], seq 1:76, ack 1, win 64240, length 75: HTTP: GET / HTTP/1.1
06:28:08.918484 IP a96-7-128-198.deploy.static.akamaitechnologies.com.80 > f6a3e2309201.43978: Flags [.], ack 76, win 64240, length 0
06:28:09.368707 IP a96-7-128-198.deploy.static.akamaitechnologies.com.80 > f6a3e2309201.43978: Flags [P.], seq 1:1519, ack 76, win 64240, length 1518: HTTP: HTTP/1.1 200 OK
06:28:09.368934 IP f6a3e2309201.43978 > a96-7-128-198.deploy.static.akamaitechnologies.com.80: Flags [.], ack 1519, win 62722, length 0
# 这里看到是curl客户端接收完数据后,主动发送关闭请求
06:28:09.369915 IP f6a3e2309201.43978 > a96-7-128-198.deploy.static.akamaitechnologies.com.80: Flags [F.], seq 76, ack 1519, win 62722, length 0
06:28:09.370398 IP a96-7-128-198.deploy.static.akamaitechnologies.com.80 > f6a3e2309201.43978: Flags [.], ack 77, win 64239, length 0
#这里服务端关闭连接处理完毕,发送fin消息给客户端,提示服务侧发送通道已经关闭清理完毕
06:28:10.068676 IP a96-7-128-198.deploy.static.akamaitechnologies.com.80 > f6a3e2309201.43978: Flags [FP.], seq 1519, ack 77, win 64239, length 0
# 客户端发送ack给服务器,告知其可以关闭连接
06:28:10.068751 IP f6a3e2309201.43978 > a96-7-128-198.deploy.static.akamaitechnologies.com.80: Flags [.], ack 1520, win 62722, length 0
此时,在客户端上执行netstat 可以看到一段时间内,会有TIME_WAIT状态的连接转态驻留
netstat -a
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State
tcp 0 0 f6a3e2309201:43978 a96-7-128-198.deploy.static.akamaitechnologies.com:http TIME_WAIT
客户端主动关闭时客户端连接状态变化 :
CONNECTED ->
主动发Fin给服务端 -> FIN_WAIT_1
收到服务端对于客户端fin的ack -> FIN_WAIT_2
收到服务端通道关闭fin -> TIME_WAIT
向服务端发送fin对应的ack -> 2MSL -> CLOSE
其他参考: developer.aliyun.com/article/916… (# 23 个问题 TCP 疑难杂症全解析(中))