一、TCP
TCP包 = IP头 (20字节) + TCP头 (32字节) + TCP数据
二、抓包
1.服务端运行 tcpdump
root@fdc276a87cec:~# tcpdump -n -v -X
2.服务端开启端口
服务端监听
root@fdc276a87cec:~# nc -l 1234
3.客户端发送数据
zxm@zxm-pc:~$ echo "abab" | nc -N 172.17.0.2 1234
4.抓包结果
root@fdc276a87cec:~# tcpdump -n -v -X
tcpdump: listening on eth0, link-type EN10MB (Ethernet), capture size 262144 bytes
05:38:20.463633 IP (tos 0x0, ttl 64, id 2300, offset 0, flags [DF], proto TCP (6), length 60)
172.17.0.1.59702 > 172.17.0.2.1234: Flags [S], cksum 0x5854 (incorrect -> 0xc532), seq 1181057195, win 64240, options [mss 1460,sackOK,TS val 3582108954 ecr 0,nop,wscale 7], length 0
0x0000: 4500 003c 08fc 4000 4006 d99a ac11 0001 E..<..@.@.......
0x0010: ac11 0002 e936 04d2 4665 80ab 0000 0000 .....6..Fe......
0x0020: a002 faf0 5854 0000 0204 05b4 0402 080a ....XT..........
0x0030: d582 a51a 0000 0000 0103 0307 ............
05:38:20.463696 IP (tos 0x0, ttl 64, id 0, offset 0, flags [DF], proto TCP (6), length 60)
172.17.0.2.1234 > 172.17.0.1.59702: Flags [S.], cksum 0x5854 (incorrect -> 0xa649), seq 1391228495, ack 1181057196, win 65160, options [mss 1460,sackOK,TS val 489764051 ecr 3582108954,nop,wscale 7], length 0
0x0000: 4500 003c 0000 4000 4006 e296 ac11 0002 E..<..@.@.......
0x0010: ac11 0001 04d2 e936 52ec 764f 4665 80ac .......6R.vOFe..
0x0020: a012 fe88 5854 0000 0204 05b4 0402 080a ....XT..........
0x0030: 1d31 34d3 d582 a51a 0103 0307 .14.........
05:38:20.463782 IP (tos 0x0, ttl 64, id 2301, offset 0, flags [DF], proto TCP (6), length 52)
172.17.0.1.59702 > 172.17.0.2.1234: Flags [.], cksum 0x584c (incorrect -> 0xd1a8), ack 1, win 502, options [nop,nop,TS val 3582108954 ecr 489764051], length 0
0x0000: 4500 0034 08fd 4000 4006 d9a1 ac11 0001 E..4..@.@.......
0x0010: ac11 0002 e936 04d2 4665 80ac 52ec 7650 .....6..Fe..R.vP
0x0020: 8010 01f6 584c 0000 0101 080a d582 a51a ....XL..........
0x0030: 1d31 34d3 .14.
05:38:20.463936 IP (tos 0x0, ttl 64, id 2302, offset 0, flags [DF], proto TCP (6), length 57)
172.17.0.1.59702 > 172.17.0.2.1234: Flags [P.], cksum 0x5851 (incorrect -> 0x04d7), seq 1:6, ack 1, win 502, options [nop,nop,TS val 3582108954 ecr 489764051], length 5
0x0000: 4500 0039 08fe 4000 4006 d99b ac11 0001 E..9..@.@.......
0x0010: ac11 0002 e936 04d2 4665 80ac 52ec 7650 .....6..Fe..R.vP
0x0020: 8018 01f6 5851 0000 0101 080a d582 a51a ....XQ..........
0x0030: 1d31 34d3 6162 6162 0a .14.abab.
05:38:20.463973 IP (tos 0x0, ttl 64, id 50481, offset 0, flags [DF], proto TCP (6), length 52)
172.17.0.2.1234 > 172.17.0.1.59702: Flags [.], cksum 0x584c (incorrect -> 0xd19b), ack 6, win 510, options [nop,nop,TS val 489764051 ecr 3582108954], length 0
0x0000: 4500 0034 c531 4000 4006 1d6d ac11 0002 E..4.1@.@..m....
0x0010: ac11 0001 04d2 e936 52ec 7650 4665 80b1 .......6R.vPFe..
0x0020: 8010 01fe 584c 0000 0101 080a 1d31 34d3 ....XL.......14.
0x0030: d582 a51a ....
05:38:20.464027 IP (tos 0x0, ttl 64, id 2303, offset 0, flags [DF], proto TCP (6), length 52)
172.17.0.1.59702 > 172.17.0.2.1234: Flags [F.], cksum 0x584c (incorrect -> 0xd1a1), seq 6, ack 1, win 502, options [nop,nop,TS val 3582108955 ecr 489764051], length 0
0x0000: 4500 0034 08ff 4000 4006 d99f ac11 0001 E..4..@.@.......
0x0010: ac11 0002 e936 04d2 4665 80b1 52ec 7650 .....6..Fe..R.vP
0x0020: 8011 01f6 584c 0000 0101 080a d582 a51b ....XL..........
0x0030: 1d31 34d3 .14.
05:38:20.464069 IP (tos 0x0, ttl 64, id 50482, offset 0, flags [DF], proto TCP (6), length 52)
172.17.0.2.1234 > 172.17.0.1.59702: Flags [F.], cksum 0x584c (incorrect -> 0xd197), seq 1, ack 7, win 510, options [nop,nop,TS val 489764052 ecr 3582108955], length 0
0x0000: 4500 0034 c532 4000 4006 1d6c ac11 0002 E..4.2@.@..l....
0x0010: ac11 0001 04d2 e936 52ec 7650 4665 80b2 .......6R.vPFe..
0x0020: 8011 01fe 584c 0000 0101 080a 1d31 34d4 ....XL.......14.
0x0030: d582 a51b ....
05:38:20.464162 IP (tos 0x0, ttl 64, id 2304, offset 0, flags [DF], proto TCP (6), length 52)
172.17.0.1.59702 > 172.17.0.2.1234: Flags [.], cksum 0x584c (incorrect -> 0xd19f), ack 2, win 502, options [nop,nop,TS val 3582108955 ecr 489764052], length 0
0x0000: 4500 0034 0900 4000 4006 d99e ac11 0001 E..4..@.@.......
0x0010: ac11 0002 e936 04d2 4665 80b2 52ec 7651 .....6..Fe..R.vQ
0x0020: 8010 01f6 584c 0000 0101 080a d582 a51b ....XL..........
0x0030: 1d31 34d4 .14.
三、分析包
分析其中一个包,客户端向服务端发送的一条带有数据的 TCP PUSH 包,内容为字符串 "abab\n",用于应用层通信
05:38:20.463936 IP (tos 0x0, ttl 64, id 2302, offset 0, flags [DF], proto TCP (6), length 57)
172.17.0.1.59702 > 172.17.0.2.1234: Flags [P.], cksum 0x5851 (incorrect -> 0x04d7), seq 1:6, ack 1, win 502, options [nop,nop,TS val 3582108954 ecr 489764051], length 5
0x0000: 4500 0039 08fe 4000 4006 d99b ac11 0001 E..9..@.@.......
0x0010: ac11 0002 e936 04d2 4665 80ac 52ec 7650 .....6..Fe..R.vP
0x0020: 8018 01f6 5851 0000 0101 080a d582 a51a ....XQ..........
0x0030: 1d31 34d3 6162 6162 0a .14.abab.
1.IP 头部解析(从 0x0000 开始,共 20 字节)
0x0000: 4500 0039 08fe 4000 4006 d99b ac11 0001
0x0010: ac11 0002
第一个字段是 4500,4500 (hex) = 0100 0101 0000 0000 (binary)
字段 | 值 | 说明 |
---|---|---|
版本 + 头部长度 | 45 | 4 表示 IPv4,5 表示 IP 头长度为 5×4 = 20 字节 |
服务类型 TOS | 00 | 通常为 0,表示默认服务类型 |
总长度 Total Length | 0039 | 十进制:57 字节,整个 IP 包的总长度(包括 IP 头 + TCP 头 + 数据) |
标识符 Identification | 08fe | 十进制 2302 |
标志位 + 偏移 | 4000 | 4000 (hex) = 0100 0000 0000 0000 (binary),DF(Don't Fragment) = 1(不分片),MF(More Fragments) = 0,偏移 = 0 |
TTL(Time To Live) | 40 | 十进制:64,每经过一个路由器减 1 |
协议 Protocol | 06 | 上层协议(6 表示 TCP) |
校验和 Checksum | d99b | 用于 IP 头部完整性校验 |
源 IP地址 | ac11 0001 | 十进制 IP:172.17.0.1 |
目标 IP 地址 | ac11 0002 | 十进制 IP:172.17.0.2 |
2.TCP 头部解析(从 0x0014 开始,共 32 字节)
0x0010: .... .... e936 04d2 4665 80ac 52ec 7650
0x0020: 8018 01f6 5851 0000 0101 080a d582 a51a
0x0030: 1d31 34d3
字段 | 值 | 说明 |
---|---|---|
源端口 | e936 | 十进制 59702,客户端端口 |
目标端口 | 04d2 | 十进制 1234,服务端端口 |
序列号 | 4665 80ac | 十进制 1181057196,数据开始位置 |
确认号 | 52ec 7650 | 十进制 1391228496,对服务端 SYN 的确认 |
数据偏移 | 80 | 80 (hex) = 1000 0000 (binary),TCP 头长度 = 8 × 4 = 32 字节,0000 = 控制标志位 |
控制标志 Flags | 18 (hex) = 0001 1000 (binary),PSH(Push)= 1,ACK(Acknowledge)= 1,其他:FIN=0, SYN=0, RST=0, URG=0 | |
窗口大小 | 01f6 | 十进制 502 接收窗口大小 |
校验和 | 584c | 注:tcpdump 提示校验和错误,实际值为 0x04d7,可能是因为网卡校验和卸载(checksum offload)导致 |
紧急指针 | 0000 | 无紧急数据 |
选项 | 0101 080a d582 a51a 1d31 34d3 | 时间戳选项 |
TCP 选项:
01 NOP
01 NOP
080a 时间戳选项(TS Option,长度 10 字节)
d582 a51a → TS val = 3582108954
1d31 34d3 → TS ecr = 489764051
- TS val(发送时间戳):3579497510
- TS ecr(回显对方时间戳):487152606
3.TCP 数据`(应用层)
0x0030: .... .... 6162 6162 0a
这是应用层数据,共 5 字节:
61 62 61 62 0a → ASCII: a b a b \n
四、整体通信流程
1.TCP 三次握手
第一次握手:
1) 客户端发起连接,发送 SYN 报文,初始序列号 seq=1181057195
2) MSS(最大段长度)为 1460
3) 支持 SACK(选择性确认)、时间戳(TS)、窗口缩放(wscale)
第二次握手:
1) 服务端响应 SYN-ACK,即 SYN 和 ACK 标志位都置位
2) 序列号 seq=1391228495,确认号 ack=1181057196(客户端的 seq + 1)
3) 时间戳 TS val=489764051,回应客户端的时间戳 TS ecr=3582108954
第三次握手:
1) 客户端发送 ACK 报文,确认号 ack=1391228496(服务端的 seq + 1)
2) 连接建立完成,可以开始数据传输
2.数据传输
数据包:
1) 客户端发送 PUSH 数据包,携带 5 字节数据(abab\n)
2) 序列号 seq=1:6,确认号 ack=1
服务端确认:
1) 服务端发送 ACK 确认收到数据,确认号 ack=6(客户端的 seq + 5)
3.TCP 四次挥手
第一次挥手:
1) 客户端发送 FIN 报文,表示关闭连接
2) 序列号 seq=6,确认号 ack=1
第二次挥手:
1) 服务端发送 FIN-ACK,即 FIN 和 ACK 标志位都置位
2) 序列号 seq=1,确认号 ack=7(客户端的 seq + 1)
第三次挥手:
1) 客户端发送 ACK 确认收到 FIN,确认号 ack=2(服务端的 seq + 1)