正文
1. 概述
本文使用wireshark捕获客户端(10.240.89.99) 向服务端( 47.95.47.253)请求页面
blog.csdn.net/hry2015/
过程中的包。先介绍TCP的三次握手协议,数据传送过程以及四次挥手协议,然后结合捕获的包学习这些协议
需要注意的是,文章接下来的部分依然使用相对序列号/确认号
2. 三次握手协议
2.1. 理论
客户端和服务端是通过三次握手协议建立TCP会话连接。建立连接的理论图如下:
第一次握手:建立连接时,客户端发送SYN到服务器,并进入SYN_SENT状态
第二次握手:服务器收到请求后,回送SYN+ACK信令到客户端,此时服务器进入SYN_RECV状态;
第三次握手:客户端收到SYN+ACK包,向服务器发送确认ACK包,客户端进入ESTABLISHED状态,服务器收到请求后也进入ESTABLISHED状态,完成三次握手,此时TCP连接成功,客户端与服务器开始传送数据
下面结合抓包学习三次握手
客户端(10.240.89.99) 向服务端( 47.95.47.253)建立连接3个包如下:
下面介绍每个包详细信息。
2.2. 第一次握手
第一次握手:建立连接时,客户端发送SYN到服务器,并进入SYN_SENT状态 数据包一些关键的属性如下:
SYN :标志位,表示请求建立连接
Seq = 0 :初始建立连接值为0,数据包的相对序列号从0开始,表示当前还没有发送数据
Ack =0:初始建立连接值为0,已经收到包的数量,表示当前没有接收到数据
WIN = 8192 来自Window size: 8192
Len = 0
MSS = 1460 来自 Maximum segment size: 1460 byte ,最长报文段,TCP包所能携带的最大数据量,不包含TCP头和Option。一般为MTU值减去IPv4头部(至少20字节)和TCP头部(至少20字节)得到
WS = 4 来自windows scale : 2 (multiply by 4): 窗口扩张,放在TCP头之外的Option,向对方声明一个shift count,作为2的指数,再乘以TCP定义的接收窗口,得到真正的TCP窗口
SACK_PERM = 1 来自SACK permitted
2.3. 第二次握手
第二次握手:服务器收到请求后,回送SYN+ACK信令到客户端,此时服务器进入SYN_RECV状态;
数据包一些关键的属性如下:
[SYN + ACK]: 标志位,同意建立连接,并回送SYN+ACK
Seq = 0 :初始建立值为0,表示当前还没有发送数据
Ack = 1 : 表示当前端成功接收的数据位数,虽然客户端没有发送任何有效数据,确认号还是被加1,因为包含SYN或FIN标志位。尽管客户端没有发送任何有效数据,确认号还是被加1,这是因为接收的包中包含SYN或FIN标志位(并不会对有效数据的计数产生影响,因为含有SYN或FIN标志位的包并不携带有效数据
其它标志和第一包相同,略
2.4. 第三次握手
第三次握手:客户端收到SYN+ACK包,向服务器发送确认ACK包,客户端进入ESTABLISHED状态,服务器收到请求后也进入ESTABLISHED状态,完成三次握手,此时TCP连接成功,客户端与服务器开始传送数据。
数据包一些关键的属性如下:
ACK :标志位,表示已经收到记录
Seq = 1 :表示当前已经发送1个数据
Ack = 1 : 表示当前端成功接收的数据位数,虽然客户端没有发送任何有效数据,确认号还是被加1,因为包含SYN或FIN标志位。尽管客户端没有发送任何有效数据,确认号还是被加1,这是因为接收的包中包含SYN或FIN标志位(并不会对有效数据的计数产生影响,因为含有SYN或FIN标志位的包并不携带有效数据)
2.5. TCP建立连接为什么是三次握手
这个问题的本质是, 信道不可靠, 但是通信双发需要就某个问题达成一致. 而要解决这个问题, 无论你在消息中包含什么信息, 三次通信是理论上的最小值. 所以三次握手不是TCP本身的要求, 而是为了满足”在不可靠信道上可靠地传输信息”这一需求所导致的.
也是为了最小的代价验证会话双方的收发功能正常:
-
第一次握手成功:说明客户端的数据可以被服务端收到,说明客户端的发功能可用,说明服务端的收功能可用。但客户端自己不知道数据是否被接收
-
第二次握手成功:说明服务端的数据可以被客户端收到,说明服务端的发功能可用,说明客户端的收功能可用。同时客户端知道自己的数据已经正确到达服务端,自己的发功能正常。但是服务端自己不知道数据是否被接收
-
第三次握手成功:说明服务端知道自己的数据已经正确到达客户端端,自己的发功能正常。至此服务成功建立
3. 客户端和服务端数据交互的过程
客户端和服务端建立连接后,开始传送数据。下面对以下场景的交互包进行分析:
客户端(10.240.89.99) 和服务端( 47.95.47.253)建立连接后,客户端向服务端传送要访问页面的信息,服务端完全接收请求后进行处理,然后服务端返回数据给服务端客户端, 客户端对收到的数据进行的确认,最后完成操作。
全部的包如下:
简化之后的数据如下:
下面结合包,详细说明传输过程中seq, ack,len的变化
3.1. 客户端(10.240.89.99)向服务端发送请求,服务端对收到数据进行确认
客户端(10.240.89.99)向服务端发送请求
包内关键信息如下:
Seq = 1 :表示当前已经发送1个数据
Next Sequence number:在完成这次的发送后,当发送新的数据时,Seq从2167开始编码
Ack = 1 : 表示当前端成功接收的1个数据位数
TCP playload:Hypertext Transfer Protocol 部分的数据量,本次传送的数据量为2166 byte
服务端(47.95.47.253)接受发送过来的2166个字节数据,在接收请求过程中,发送两次ACK包