1. tcpdump 抓取Tcp报文
1. 现在有一对tcp程序
- 服务端地址:192.168.52.39:8080。
- 客户端地址:192.168.52.67。
- 连接建立后客户端发送数据: ABCDEF。
- 服务器收到数据后,发送数据:ABCDEFGH。
- 客户端断开连接。
2. tcpdump抓取Tcp报文
|
|
3. 抓取结果
|
|
2. 分析抓包结果
|
|
三次握手、四次挥手、一个数据报文,一个数据报文的ACK,算起来9个报文,下面分析一下抓取的报文。
2.1. 三次握手
|
|
简单分析一下:
192.168.52.67.33762 > 192.168.52.39.8080: 报文的源地址 > 目标地址
Flags [S]: 同步报文段,由客户端发送,表示请求建立一个连接。
Flags [S.]: 同步+确认报文段,由服务端发送,做了两件事: 1.同步,表示同意客户端的连接请求。2.响应客户端的SYN报文。
Flags [.]: 确认报文。
seq 3666571938: 客户端ISN值,就是报文序号的初始值。
seq 394631164: 服务端ISN值,两个传输方向分别有各自的ISN值。
ack 3666571939: 确认序号,表示服务端已经收到客户端的报文,确认序号就是接收到的报文的seq+1。
options [mss 1460,sackOK,TS val 1128528921 ecr 0,nop,wscale 7]: TCP头部结构中的头部选项。
length 0: 报文的数据长度,SYN 包不携带数据,所以为0。
以上就是“三次握手”。
2.2. 数据发送与响应
|
|
seq 1:7: 数据报文的起始序列号为1(方向: 客户端->服务器),报文所携带的字节编号是[1, 7)。
length 6: HTTP: 报文携带的数据长度为6字节,识别为HTTP报文是因为使用了8080端口。
seq 1:9: 数据报文的起始序列号为1(方向: 服务器->客户端)。
ack 7: 确认序号为7,就是对于来自客户端的数据报文进行响应,表示收到了这个报文,ack=seq+length+1,也就是下一个报文的起始序列号。
注意:
tcp虽然也是一个一个报文发送的,但是tcp是流式协议,序列号用于表示一次网络通信过程中,所传输数据的每一个字节的编号,注意了是字节的编号,在一次通信活动中,数据字节的编号是连续的。因为是流式协议,对于应用层协议来说,tcp数据流是没有边界的,会发生所谓的粘包问题,这需要应用层去解决,毕竟tcp只负责数据的可靠传输,而不管数据从哪里开始,从到哪里结束。
ACK报文:
例如一个报文,字节编号是[100, 201),这个报文的应答报文的ACK就是201,也就是下一个报文的数据字节的起始编号,通过这个方式告诉发送端,这个报文已经收到,可以开始发送下一个报文了。
2.3. 四次挥手
|
|
192.168.52.67.33762 > 192.168.52.39.8080: Flags [F.]: 客户端发送了关闭连接的请求。
192.168.52.39.8080 > 192.168.52.67.33762: Flags [.]: 服务器收到客户端请求后,发送了确认包。
192.168.52.39.8080 > 192.168.52.67.33762: Flags [F.]: 服务器发送了关闭连接的请求。
192.168.52.67.33762 > 192.168.52.39.8080: Flags [.]: 客户端收到服务器的关闭请求后,发送了确认包。
双方都要发送关闭连接请求,保证双方都没有数据要发送。有些机器挥手只有3个报文,因为中间的两个报文合并在一起了。
3. 其他
|
|