一、分析连接过程
1.tcpdump -n
root@07c6d9bc766d:~# tcpdump -n
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
# 客户端 → 服务端:SYN 包
07:03:22.672793 IP 172.18.0.1.35940 > 172.18.0.2.80: Flags [S], seq 179206035, win 64240, options [mss 1460,sackOK,TS val 916745958 ecr 0,nop,wscale 7], length 0
# 服务端 → 客户端:SYN-ACK 包
07:03:22.672804 IP 172.18.0.2.80 > 172.18.0.1.35940: Flags [S.], seq 3213020767, ack 179206036, win 65160, options [mss 1460,sackOK,TS val 971067608 ecr 916745958,nop,wscale 7], length 0
# 客户端 → 服务端:ACK 包
07:03:22.672815 IP 172.18.0.1.35940 > 172.18.0.2.80: Flags [.], ack 1, win 502, options [nop,nop,TS val 916745958 ecr 971067608], length 0
# 客户端 → 服务端:HTTP GET 请求
07:03:22.672835 IP 172.18.0.1.35940 > 172.18.0.2.80: Flags [P.], seq 1:75, ack 1, win 502, options [nop,nop,TS val 916745958 ecr 971067608], length 74: HTTP: GET / HTTP/1.1
# 服务端 → 客户端:ACK 确认
07:03:22.672837 IP 172.18.0.2.80 > 172.18.0.1.35940: Flags [.], ack 75, win 509, options [nop,nop,TS val 971067608 ecr 916745958], length 0
# 服务端 → 客户端:HTTP 响应头。
07:03:22.672963 IP 172.18.0.2.80 > 172.18.0.1.35940: Flags [P.], seq 1:236, ack 75, win 509, options [nop,nop,TS val 971067608 ecr 916745958], length 235: HTTP: HTTP/1.1 200 OK
# 客户端 → 服务端:ACK 确认。
07:03:22.672975 IP 172.18.0.1.35940 > 172.18.0.2.80: Flags [.], ack 236, win 501, options [nop,nop,TS val 916745958 ecr 971067608], length 0
# 服务端 → 客户端:HTTP 响应体(正文)。服务端发送响应正文,共 13 字节。
07:03:22.672986 IP 172.18.0.2.80 > 172.18.0.1.35940: Flags [P.], seq 236:249, ack 75, win 509, options [nop,nop,TS val 971067608 ecr 916745958], length 13: HTTP
# 客户端 → 服务端:ACK 确认。
07:03:22.672989 IP 172.18.0.1.35940 > 172.18.0.2.80: Flags [.], ack 249, win 501, options [nop,nop,TS val 916745958 ecr 971067608], length 0
# 客户端 → 服务端:FIN 包。
07:03:22.673018 IP 172.18.0.1.35940 > 172.18.0.2.80: Flags [F.], seq 75, ack 249, win 501, options [nop,nop,TS val 916745958 ecr 971067608], length 0
# 服务端 → 客户端:ACK 确认。
07:03:22.673027 IP 172.18.0.2.80 > 172.18.0.1.35940: Flags [F.], seq 249, ack 76, win 509, options [nop,nop,TS val 971067608 ecr 916745958], length 0
# 客户端 → 服务端:ACK 确认。
07:03:22.673036 IP 172.18.0.1.35940 > 172.18.0.2.80: Flags [.], ack 250, win 501, options [nop,nop,TS val 916745959 ecr 971067608], length 0
2.tcpdump -n -X
root@07c6d9bc766d:~# tcpdump -n -X
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
# 客户端 → 服务端:SYN 包
07:10:04.445848 IP 172.18.0.1.40974 > 172.18.0.2.80: Flags [S], seq 2766281137, win 64240, options [mss 1460,sackOK,TS val 917147731 ecr 0,nop,wscale 7], length 0
0x0000: 4500 003c ec68 4000 4006 f62b ac12 0001 E..<.h@.@..+....
0x0010: ac12 0002 a00e 0050 a4e2 19b1 0000 0000 .......P........
0x0020: a002 faf0 5856 0000 0204 05b4 0402 080a ....XV..........
0x0030: 36aa 9053 0000 0000 0103 0307 6..S........
# 服务端 → 客户端:SYN-ACK 包
07:10:04.445859 IP 172.18.0.2.80 > 172.18.0.1.40974: Flags [S.], seq 3286744980, ack 2766281138, win 65160, options [mss 1460,sackOK,TS val 971469381 ecr 917147731,nop,wscale 7], length 0
0x0000: 4500 003c 0000 4000 4006 e294 ac12 0002 E..<..@.@.......
0x0010: ac12 0001 0050 a00e c3e7 bf94 a4e2 19b2 .....P..........
0x0020: a012 fe88 5856 0000 0204 05b4 0402 080a ....XV..........
0x0030: 39e7 7245 36aa 9053 0103 0307 9.rE6..S....
# 客户端 → 服务端:ACK 包
07:10:04.445869 IP 172.18.0.1.40974 > 172.18.0.2.80: Flags [.], ack 1, win 502, options [nop,nop,TS val 917147731 ecr 971469381], length 0
0x0000: 4500 0034 ec69 4000 4006 f632 ac12 0001 E..4.i@.@..2....
0x0010: ac12 0002 a00e 0050 a4e2 19b2 c3e7 bf95 .......P........
0x0020: 8010 01f6 584e 0000 0101 080a 36aa 9053 ....XN......6..S
0x0030: 39e7 7245 9.rE
# 客户端 → 服务端:HTTP GET 请求
07:10:04.445889 IP 172.18.0.1.40974 > 172.18.0.2.80: Flags [P.], seq 1:75, ack 1, win 502, options [nop,nop,TS val 917147731 ecr 971469381], length 74: HTTP: GET / HTTP/1.1
0x0000: 4500 007e ec6a 4000 4006 f5e7 ac12 0001 E..~.j@.@.......
0x0010: ac12 0002 a00e 0050 a4e2 19b2 c3e7 bf95 .......P........
0x0020: 8018 01f6 5898 0000 0101 080a 36aa 9053 ....X.......6..S
0x0030: 39e7 7245 4745 5420 2f20 4854 5450 2f31 9.rEGET./.HTTP/1
0x0040: 2e31 0d0a 486f 7374 3a20 3137 322e 3138 .1..Host:.172.18
0x0050: 2e30 2e32 0d0a 5573 6572 2d41 6765 6e74 .0.2..User-Agent
0x0060: 3a20 6375 726c 2f37 2e38 312e 300d 0a41 :.curl/7.81.0..A
0x0070: 6363 6570 743a 202a 2f2a 0d0a 0d0a ccept:.*/*....
# 服务端 → 客户端:ACK 确认
07:10:04.445891 IP 172.18.0.2.80 > 172.18.0.1.40974: Flags [.], ack 75, win 509, options [nop,nop,TS val 971469381 ecr 917147731], length 0
0x0000: 4500 0034 2e64 4000 4006 b438 ac12 0002 E..4.d@.@..8....
0x0010: ac12 0001 0050 a00e c3e7 bf95 a4e2 19fc .....P..........
0x0020: 8010 01fd 584e 0000 0101 080a 39e7 7245 ....XN......9.rE
0x0030: 36aa 9053 6..S
# 服务端 → 客户端:HTTP 响应头。
07:10:04.446012 IP 172.18.0.2.80 > 172.18.0.1.40974: Flags [P.], seq 1:236, ack 75, win 509, options [nop,nop,TS val 971469381 ecr 917147731], length 235: HTTP: HTTP/1.1 200 OK
0x0000: 4500 011f 2e65 4000 4006 b34c ac12 0002 E....e@.@..L....
0x0010: ac12 0001 0050 a00e c3e7 bf95 a4e2 19fc .....P..........
0x0020: 8018 01fd 5939 0000 0101 080a 39e7 7245 ....Y9......9.rE
0x0030: 36aa 9053 4854 5450 2f31 2e31 2032 3030 6..SHTTP/1.1.200
0x0040: 204f 4b0d 0a53 6572 7665 723a 206e 6769 .OK..Server:.ngi
0x0050: 6e78 2f31 2e32 332e 330d 0a44 6174 653a nx/1.23.3..Date:
0x0060: 2053 6174 2c20 3236 204a 756c 2032 3032 .Sat,.26.Jul.202
0x0070: 3520 3037 3a31 303a 3034 2047 4d54 0d0a 5.07:10:04.GMT..
0x0080: 436f 6e74 656e 742d 5479 7065 3a20 7465 Content-Type:.te
0x0090: 7874 2f68 746d 6c0d 0a43 6f6e 7465 6e74 xt/html..Content
0x00a0: 2d4c 656e 6774 683a 2031 330d 0a4c 6173 -Length:.13..Las
0x00b0: 742d 4d6f 6469 6669 6564 3a20 5361 742c t-Modified:.Sat,
0x00c0: 2032 3620 4a75 6c20 3230 3235 2030 363a .26.Jul.2025.06:
0x00d0: 3536 3a34 3820 474d 540d 0a43 6f6e 6e65 56:48.GMT..Conne
0x00e0: 6374 696f 6e3a 206b 6565 702d 616c 6976 ction:.keep-aliv
0x00f0: 650d 0a45 5461 673a 2022 3638 3834 3763 e..ETag:."68847c
0x0100: 3330 2d64 220d 0a41 6363 6570 742d 5261 30-d"..Accept-Ra
0x0110: 6e67 6573 3a20 6279 7465 730d 0a0d 0a nges:.bytes....
# 客户端 → 服务端:ACK 确认。
07:10:04.446023 IP 172.18.0.1.40974 > 172.18.0.2.80: Flags [.], ack 236, win 501, options [nop,nop,TS val 917147731 ecr 971469381], length 0
0x0000: 4500 0034 ec6b 4000 4006 f630 ac12 0001 E..4.k@.@..0....
0x0010: ac12 0002 a00e 0050 a4e2 19fc c3e7 c080 .......P........
0x0020: 8010 01f5 584e 0000 0101 080a 36aa 9053 ....XN......6..S
0x0030: 39e7 7245 9.rE
# 服务端 → 客户端:HTTP 响应体(正文)。服务端发送响应正文,共 13 字节。
07:10:04.446037 IP 172.18.0.2.80 > 172.18.0.1.40974: Flags [P.], seq 236:249, ack 75, win 509, options [nop,nop,TS val 971469382 ecr 917147731], length 13: HTTP
0x0000: 4500 0041 2e66 4000 4006 b429 ac12 0002 E..A.f@.@..)....
0x0010: ac12 0001 0050 a00e c3e7 c080 a4e2 19fc .....P..........
0x0020: 8018 01fd 585b 0000 0101 080a 39e7 7246 ....X[......9.rF
0x0030: 36aa 9053 4865 6c6c 6f20 576f 726c 6421 6..SHello.World!
0x0040: 0a .
# 客户端 → 服务端:ACK 确认。
07:10:04.446040 IP 172.18.0.1.40974 > 172.18.0.2.80: Flags [.], ack 249, win 501, options [nop,nop,TS val 917147732 ecr 971469382], length 0
0x0000: 4500 0034 ec6c 4000 4006 f62f ac12 0001 E..4.l@.@../....
0x0010: ac12 0002 a00e 0050 a4e2 19fc c3e7 c08d .......P........
0x0020: 8010 01f5 584e 0000 0101 080a 36aa 9054 ....XN......6..T
0x0030: 39e7 7246 9.rF
# 客户端 → 服务端:FIN 包。
07:10:04.446108 IP 172.18.0.1.40974 > 172.18.0.2.80: Flags [F.], seq 75, ack 249, win 501, options [nop,nop,TS val 917147732 ecr 971469382], length 0
0x0000: 4500 0034 ec6d 4000 4006 f62e ac12 0001 E..4.m@.@.......
0x0010: ac12 0002 a00e 0050 a4e2 19fc c3e7 c08d .......P........
0x0020: 8011 01f5 584e 0000 0101 080a 36aa 9054 ....XN......6..T
0x0030: 39e7 7246 9.rF
# 服务端 → 客户端:ACK 确认。
07:10:04.446164 IP 172.18.0.2.80 > 172.18.0.1.40974: Flags [F.], seq 249, ack 76, win 509, options [nop,nop,TS val 971469382 ecr 917147732], length 0
0x0000: 4500 0034 2e67 4000 4006 b435 ac12 0002 E..4.g@.@..5....
0x0010: ac12 0001 0050 a00e c3e7 c08d a4e2 19fd .....P..........
0x0020: 8011 01fd 584e 0000 0101 080a 39e7 7246 ....XN......9.rF
0x0030: 36aa 9054
# 客户端 → 服务端:ACK 确认。 6..T
07:10:04.446175 IP 172.18.0.1.40974 > 172.18.0.2.80: Flags [.], ack 250, win 501, options [nop,nop,TS val 917147732 ecr 971469382], length 0
0x0000: 4500 0034 ec6e 4000 4006 f62d ac12 0001 E..4.n@.@..-....
0x0010: ac12 0002 a00e 0050 a4e2 19fd c3e7 c08e .......P........
0x0020: 8010 01f5 584e 0000 0101 080a 36aa 9054 ....XN......6..T
0x0030: 39e7 7246 9.rF
3.tcpdump -n -A
root@07c6d9bc766d:~# tcpdump -n -A
tcpdump: verbose output suppressed, use -v[v]... for full protocol decode
listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
# 客户端 → 服务端:SYN 包
07:13:28.153103 IP 172.18.0.1.46458 > 172.18.0.2.80: Flags [S], seq 2455576118, win 64240, options [mss 1460,sackOK,TS val 917351439 ecr 0,nop,wscale 7], length 0
E..<%.@.@............z.P.].6........XV.........
6...........
# 服务端 → 客户端:SYN-ACK 包
07:13:28.153114 IP 172.18.0.2.80 > 172.18.0.1.46458: Flags [S.], seq 69042663, ack 2455576119, win 65160, options [mss 1460,sackOK,TS val 971673089 ecr 917351439,nop,wscale 7], length 0
E..<..@.@............P.z.....].7....XV.........
9...6.......
# 客户端 → 服务端:ACK 包
07:13:28.153125 IP 172.18.0.1.46458 > 172.18.0.2.80: Flags [.], ack 1, win 502, options [nop,nop,TS val 917351439 ecr 971673089], length 0
E..4%.@.@............z.P.].7........XN.....
6...9...
# 客户端 → 服务端:HTTP GET 请求
07:13:28.153145 IP 172.18.0.1.46458 > 172.18.0.2.80: Flags [P.], seq 1:75, ack 1, win 502, options [nop,nop,TS val 917351439 ecr 971673089], length 74: HTTP: GET / HTTP/1.1
E..~%.@.@............z.P.].7........X......
6...9...GET / HTTP/1.1
Host: 172.18.0.2
User-Agent: curl/7.81.0
Accept: */*
# 服务端 → 客户端:ACK 确认
07:13:28.153146 IP 172.18.0.2.80 > 172.18.0.1.46458: Flags [.], ack 75, win 509, options [nop,nop,TS val 971673089 ecr 917351439], length 0
E..4&:@.@..b.........P.z.....]......XN.....
9...6...
# 服务端 → 客户端:HTTP 响应头。
07:13:28.153269 IP 172.18.0.2.80 > 172.18.0.1.46458: Flags [P.], seq 1:236, ack 75, win 509, options [nop,nop,TS val 971673089 ecr 917351439], length 235: HTTP: HTTP/1.1 200 OK
E...&;@.@..v.........P.z.....]......Y9.....
9...6...HTTP/1.1 200 OK
Server: nginx/1.23.3
Date: Sat, 26 Jul 2025 07:13:28 GMT
Content-Type: text/html
Content-Length: 13
Last-Modified: Sat, 26 Jul 2025 06:56:48 GMT
Connection: keep-alive
ETag: "68847c30-d"
Accept-Ranges: bytes
# 客户端 → 服务端:ACK 确认。
07:13:28.153280 IP 172.18.0.1.46458 > 172.18.0.2.80: Flags [.], ack 236, win 501, options [nop,nop,TS val 917351439 ecr 971673089], length 0
E..4%.@.@............z.P.]..........XN.....
6...9...
# 服务端 → 客户端:HTTP 响应体(正文)。服务端发送响应正文,共 13 字节。
07:13:28.153290 IP 172.18.0.2.80 > 172.18.0.1.46458: Flags [P.], seq 236:249, ack 75, win 509, options [nop,nop,TS val 971673089 ecr 917351439], length 13: HTTP
E..A&<@.@..S.........P.z.....]......X[.....
9...6...Hello World!
# 客户端 → 服务端:ACK 确认。
07:13:28.153292 IP 172.18.0.1.46458 > 172.18.0.2.80: Flags [.], ack 249, win 501, options [nop,nop,TS val 917351439 ecr 971673089], length 0
E..4%.@.@............z.P.]..........XN.....
6...9...
# 客户端 → 服务端:FIN 包。
07:13:28.153364 IP 172.18.0.1.46458 > 172.18.0.2.80: Flags [F.], seq 75, ack 249, win 501, options [nop,nop,TS val 917351439 ecr 971673089], length 0
E..4%.@.@............z.P.]..........XN.....
6...9...
# 服务端 → 客户端:ACK 确认。
07:13:28.153387 IP 172.18.0.2.80 > 172.18.0.1.46458: Flags [F.], seq 249, ack 76, win 509, options [nop,nop,TS val 971673089 ecr 917351439], length 0
E..4&=@.@.._.........P.z.....]......XN.....
9...6...
# 客户端 → 服务端:ACK 确认。
07:13:28.153399 IP 172.18.0.1.46458 > 172.18.0.2.80: Flags [.], ack 250, win 501, options [nop,nop,TS val 917351439 ecr 971673089], length 0
E..4%.@.@............z.P.]..........XN.....
6...9...
4.tcpdump -v -n
root@225f19598cc3:/# tcpdump -v -n
tcpdump: listening on eth0, link-type EN10MB (Ethernet), snapshot length 262144 bytes
# 客户端 → 服务端:SYN 包。客户端发起连接请求,标志位为 [S](SYN),表示同步请求,初始序列号 seq=167702838,MSS(最大报文段长度)为 1460 字节
# 协议类型和 IP 头部信息
# tos 0x0:服务类型
# ttl 64:生存时间.每经过一个路由器减 1,减到 0 时丢弃。此处为 64,说明该数据包最多还能经过 64 跳
# id 55449:IP ID(标识符),用于唯一标识当前主机发送的数据报,主要用于分片重组。
# offset 0:分片偏移量,表示该数据包在原始数据报中的位置。这里为 0,表示这是第一个(也是唯一一个)分片。
# flags [DF]:标志位,DF 表示 Don't Fragment(不分片)。TCP 通常会设置此标志以避免分片。
# proto TCP (6):上层协议为 TCP,协议号为 6。
# length 60:P 总长度为 60 字节,包括 IP 头(20 字节) + TCP 头(20 字节)+ 可能的选项部分(20 字节)。
# Flags [S]:[S] 表示 SYN 标志位被置 1。
# seq 167702838:Sequence Number(序列号):本次发送的第一个字节的编号,用于保证顺序可靠传输。初始值随机生成,这里是 167702838。
# win 64240:Window Size(窗口大小):接收方当前可以接收的数据量,单位是字节。表示客户端目前允许服务端发送最多 64240 字节 的数据而不必等待确认。
# options:TCP 选项(Options)。
# length 0:表示 TCP 数据部分长度为 0,这是一个纯控制包(SYN),没有携带应用层数据。
09:25:52.414604 IP (tos 0x0, ttl 64, id 55449, offset 0, flags [DF], proto TCP (6), length 60)
172.18.0.1.43614 > 172.18.0.2.80: Flags [S], cksum 0x5856 (incorrect -> 0x7098), seq 167702838, win 64240, options [mss 1460,sackOK,TS val 2618638934 ecr 0,nop,wscale 7], length 0
# 服务端 → 客户端:SYN-ACK 包。服务端回应连接请求,标志位为 [S.](SYN + ACK),序列号 seq=4227940362,确认号 ack=167702839(即客户端初始序列号 + 1)。
09:25:52.414621 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
172.18.0.2.80 > 172.18.0.1.43614: Flags [S.], cksum 0x5856 (incorrect -> 0x5e4c), seq 4227940362, ack 167702839, win 65160, options [mss 1460,sackOK,TS val 476034615 ecr 2618638934,nop,wscale 7], length 0
# 客户端 → 服务端:ACK 包。客户端发送确认包,标志位为 [.](仅 ACK),确认号 ack=1,表示对服务端序列号的确认,此时 TCP 连接已建立。
09:25:52.414638 IP (tos 0x0, ttl 64, id 55450, offset 0, flags [DF], proto TCP (6), length 52)
172.18.0.1.43614 > 172.18.0.2.80: Flags [.], cksum 0x584e (incorrect -> 0x89ab), ack 1, win 502, options [nop,nop,TS val 2618638934 ecr 476034615], length 0
# 客户端 → 服务端:HTTP GET 请求。客户端发送 HTTP GET 请求,标志位为 [P.](PSH + ACK),表示有数据推送,数据内容是 HTTP 请求头,请求根路径 /。
# IP length = 126:表示整个 IP 包的长度为 126 字节。表示整个 IP 包的长度为 126 字节。IP 头部(通常 20 字节),TCP 头部(通常 20 字节 + 选项如 TS),数据部分(74 字节)。
# TCP length = 74:表示 TCP 的数据部分(即 HTTP 请求头)长度是 74 字节。
09:25:52.414679 IP (tos 0x0, ttl 64, id 55451, offset 0, flags [DF], proto TCP (6), length 126)
172.18.0.1.43614 > 172.18.0.2.80: Flags [P.], cksum 0x5898 (incorrect -> 0x864f), seq 1:75, ack 1, win 502, options [nop,nop,TS val 2618638934 ecr 476034615], length 74: HTTP, length: 74
GET / HTTP/1.1
Host: 172.18.0.2
User-Agent: curl/7.81.0
Accept: */*
# 服务端 → 客户端:ACK 确认。服务端确认收到客户端的数据。
09:25:52.414684 IP (tos 0x0, ttl 64, id 37395, offset 0, flags [DF], proto TCP (6), length 52)
172.18.0.2.80 > 172.18.0.1.43614: Flags [.], cksum 0x584e (incorrect -> 0x895a), ack 75, win 509, options [nop,nop,TS val 476034615 ecr 2618638934], length 0
# 服务端 → 客户端:HTTP 响应头。内容长度为 13 字节,说明正文很小。
09:25:52.414809 IP (tos 0x0, ttl 64, id 37396, offset 0, flags [DF], proto TCP (6), length 287)
172.18.0.2.80 > 172.18.0.1.43614: Flags [P.], cksum 0x5939 (incorrect -> 0xec06), seq 1:236, ack 75, win 509, options [nop,nop,TS val 476034615 ecr 2618638934], length 235: HTTP, length: 235
HTTP/1.1 200 OK
Server: nginx/1.24.0
Date: Mon, 14 Jul 2025 09:25:52 GMT
Content-Type: text/html
Content-Length: 13
Last-Modified: Tue, 08 Jul 2025 09:16:33 GMT
Connection: keep-alive
ETag: "686ce1f1-d"
Accept-Ranges: bytes
# 客户端 → 服务端:ACK 确认。
09:25:52.414829 IP (tos 0x0, ttl 64, id 55452, offset 0, flags [DF], proto TCP (6), length 52)
172.18.0.1.43614 > 172.18.0.2.80: Flags [.], cksum 0x584e (incorrect -> 0x8877), ack 236, win 501, options [nop,nop,TS val 2618638934 ecr 476034615], length 0
# 服务端 → 客户端:HTTP 响应体(正文)。服务端发送响应正文,共 13 字节。
09:25:52.414854 IP (tos 0x0, ttl 64, id 37397, offset 0, flags [DF], proto TCP (6), length 65)
172.18.0.2.80 > 172.18.0.1.43614: Flags [P.], cksum 0x585b (incorrect -> 0x2c6b), seq 236:249, ack 75, win 509, options [nop,nop,TS val 476034615 ecr 2618638934], length 13: HTTP
# 客户端 → 服务端:ACK 确认。客户端再次确认收到全部数据。
09:25:52.414866 IP (tos 0x0, ttl 64, id 55453, offset 0, flags [DF], proto TCP (6), length 52)
172.18.0.1.43614 > 172.18.0.2.80: Flags [.], cksum 0x584e (incorrect -> 0x886a), ack 249, win 501, options [nop,nop,TS val 2618638934 ecr 476034615], length 0
# 客户端 → 服务端:FIN 包。客户端发送 FIN 包,表示要关闭连接,标志位为 [F.](FIN + ACK),序列号为 75,表示这是最后一个数据字节。
09:25:52.414960 IP (tos 0x0, ttl 64, id 55454, offset 0, flags [DF], proto TCP (6), length 52)
172.18.0.1.43614 > 172.18.0.2.80: Flags [F.], cksum 0x584e (incorrect -> 0x8869), seq 75, ack 249, win 501, options [nop,nop,TS val 2618638934 ecr 476034615], length 0
# 服务端 → 客户端:ACK 确认。服务端回应一个 ACK,并发送自己的 FIN 包,标志位为 [F.](FIN + ACK),确认号为 76,表示已接收客户端的 FIN。
09:25:52.414991 IP (tos 0x0, ttl 64, id 37398, offset 0, flags [DF], proto TCP (6), length 52)
172.18.0.2.80 > 172.18.0.1.43614: Flags [F.], cksum 0x584e (incorrect -> 0x8860), seq 249, ack 76, win 509, options [nop,nop,TS val 476034615 ecr 2618638934], length 0
# 客户端 → 服务端:ACK 确认。客户端发送最终的 ACK,完成四次挥手,连接完全关闭。
09:25:52.415010 IP (tos 0x0, ttl 64, id 55455, offset 0, flags [DF], proto TCP (6), length 52)
172.18.0.1.43614 > 172.18.0.2.80: Flags [.], cksum 0x584e (incorrect -> 0x8868), ack 250, win 501, options [nop,nop,TS val 2618638934 ecr 476034615], length 0
二、TCP 连接全过程 seq 与 ack 变化表
在第一次挥手之后,如果被动方没有数据要发给主动方。第二和第三次挥手是有可能合并传输的,服务端把 ACK 和 FIN 放在一个包里(即合并了第 2 和第 3 步)。这样就出现了三次挥手。
方向 | 标志位 | seq 值(起始) |
seq 范围 |
数据长度 | ack 值 |
seq 来源说明 |
ack 来源说明 |
---|---|---|---|---|---|---|---|
C→S | [S] |
167702838 |
- | 0 | - | 客户端初始 SEQ(随机生成) | 无 ACK(SYN 包) |
S→C | [S.] |
4227940362 |
- | 0 | 167702839 |
服务端初始 SEQ(随机生成) | 客户端 SEQ + 1(SYN 占一个字节) |
C→S | [.] |
167702839 |
- | 0 | 4227940363 |
上一次客户端 SEQ + 1(SYN 占一个字节) | 服务端 SEQ + 1(SYN 占一个字节) |
C→S | [P.] |
1 |
1:75 |
74 | 1 |
上一次客户端 SEQ(167702839)后开始新数据流,起始为 1(可能是相对序号) | 上一次服务端 SEQ(4227940362)+1 后已确认 |
S→C | [.] |
1 |
- | 0 | 75 |
上一次服务端 SEQ(4227940362)后开始新数据流,起始为 1(相对序号) | 客户端上一次 SEQ(1)+ 数据长度(74) |
S→C | [P.] |
1 |
1:236 |
235 | 75 |
继续使用当前 SEQ | 保持不变 |
C→S | [.] |
75 |
- | 0 | 236 |
上一次客户端 SEQ(1)+ 数据长度(74) | 服务端上一次 SEQ(1)+ 数据长度(235) |
S→C | [P.] |
236 |
236:249 |
13 | 75 |
上一次服务端 SEQ(1)+ 数据长度(235) | 保持不变 |
C→S | [.] |
75 |
- | 0 | 249 |
保持不变 | 服务端上一次 SEQ(236)+ 数据长度(13) |
C→S | [F.] |
75 |
- | 0 | 249 |
保持不变 | 保持不变 |
S→C | [.] |
249 |
- | 0 | 76 |
上一次服务端 SEQ(236)+ 数据长度(13) | 客户端 FIN 的 SEQ(75)+1 |
S→C | [F.] |
249 |
- | 0 | 76 |
保持不变 | 保持不变 |
C→S | [.] |
76 |
- | 0 | 250 |
客户端 FIN 的 SEQ(75)+1 | 服务端 FIN 的 SEQ(249)+1 |
1.初始连接(三次握手)
SYN 报文**会占用一个序列号(即使没有数据)
- 客户端发送 SYN:
seq = 167702838
- 服务端回复 SYN/ACK:
seq = 4227940362
,ack = 167702838 + 1 = 167702839
- 客户端最后 ACK:
seq = 167702838 + 1 = 167702839
,ack = 4227940362 + 1 = 4227940363
2.数据传输阶段
HTTP 请求(GET /)
- 客户端发送数据:
seq = 1
(可能基于连接建立后的相对序号) - 数据长度:74 字节 → 下一个期望收到的序号是
1 + 74 = 75
- 服务端返回 ACK:
ack = 75
服务端响应(HTTP 200 OK)
-
第一包数据:
seq = 1
, 长度 235 → 下一个是1 + 235 = 236
-
客户端返回 ACK:
ack = 236
-
第二包数据:
seq = 236
, 长度 13 → 下一个是236 + 13 = 249
-
客户端返回 ACK:
ack = 249
3.四次挥手
客户端发送 FIN
- 当前客户端最后一个数据 SEQ 是
75
(上次发送的是 HTTP 请求结束位置) - FIN 标志也占一个 SEQ → 所以发送
seq = 75
,Flags [F.]
服务端回应 ACK
- 确认客户端 FIN:
ack = 75 + 1 = 76
服务端发送 FIN
- 当前服务端最后一个数据 SEQ 是
249
(上一个数据包结束在 249) - 发送
seq = 249
,Flags [F.]
客户端回应 ACK
- 确认服务端 FIN:
ack = 249 + 1 = 250
类型 | seq 增长方式 | ack 计算方式 |
---|---|---|
普通数据段 | 当前 seq + 数据长度 |
对方 seq + 数据长度 |
SYN/FIN 标志 | 占用 1 个 seq | 对方 seq + 1 |
纯 ACK(无数据) | 不增长 | 对方 seq + 数据长度(或 +1 若有 SYN/FIN) |
三、tcpdump 参数
tcpdump -i eth0 -nn port 80 -A -s 0
tcpdump -i eth0 -nn port 80 -X -s 0
tcpdump -i any -nn port 80 -X -s 0
如果你没有加上 -X、-xx、-A 等参数,tcpdump 默认不会打印 payload(正文)内容
- -i eth0: 指定网卡
- -i any:监听所有网卡
- -nn: 不解析主机名和服务名
- port 80: 只抓 HTTP 流量
- -A: 以 ASCII 形式显示数据内容
- -s 0: 抓取完整包(不受 snaplen 截断)
四、常见的 TCP Flags 标志位
Flag | 缩写 | 含义 |
---|---|---|
SYN | [S] |
同步序号,用于发起一个连接。 |
ACK | [.] |
确认序号有效。通常单独显示为点(. ),但在其他标志存在时会明确写出。 |
FIN | [F] |
发送端已经完成数据发送,请求关闭连接。 |
RST | [R] |
重置连接。用于异常终止连接。 |
PSH | [P] |
推送功能,提示接收方尽快将数据提交给应用程序,而不是等待更多的数据到来。 |
URG | [U] |
紧急指针字段有效,表示该数据段中有紧急数据。 |
ECE | [E] |
ECN-Echo,用于显式拥塞通知机制。 |
CWR | [C] |
拥塞窗口减少,用于显式拥塞通知机制。 |