通过wireshark学习三次握手、四次挥手、数据传输

发表于:2019-3-05 17:29

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:hry2015    来源:CSDN

分享:
  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包
  第一次发送ACK包
  Seq: 1 Ack: 1449: 说明现在共收到1449字节数据
 
  第二次发送ACK包
  Seq: 1 Ack: 2167: 说明现在共收到2167字节数据,说明我们已经接收到全部的数据。
  
  3.2. 服务端(47.95.47.253)向对方推送数据,在发送的过程中,服务端(10.240.89.99)同时接收数据并向发送方发送确认的消息
  由于服务端向客户端发送14117字节数据,已经知道测试网络Ethernet II 帧一次最大负载值为1502,再加上分析包我们发现每个包最大的数据负载为1448字节,所有此数据被拆分成10个TCP包进行发送。客户端采用延迟确信,平均收到2个数据包发送一个确认包
  
  这里先分析第一组里数据,即第一个框3个包的信息
  服务端(47.95.47.253)第一次推送记录:1448字节的数据
  ACK
  Seq = 1
  # Next Sequence number:在完成这次的发送后,当发送新的数据时,Seq从1449开始编码
  Ack = 2167
  
  服务端(47.95.47.253)第二次推送记录:1448字节的数据
  ACK
  Seq = 1449
  Next Sequence number:在完成这次的发送后,当发送新的数据时,Seq从2897开始编码
  Ack = 2167
  
  客户端(10.240.89.99)第一次对收到的数据进行确认
  ACK
  Seq = 2167
  Ack = 2897:已经收到 2896(2897-1)个字节数据
 
  后面还有四次类似操作。虽然最后一次显示的是http(实质也是tcp)但和之前的交互实质是相同的,最后一次推送的数据大小是1139。后面的包就不一一说明。
  显示为http的协议的包特殊说明:
  和之前tcp包,不同的是有个特殊字段“[10 Reassembled TCP Segmetns (14117 bytes): ….] ”:此字段表明从#254(1448)到 #267(1085)共10个数据包组成一个完整http内容,也说明这次的HTTP的请求的内容被拆分为10个包给客户端
  
  4. 四次挥手:关闭TCP连接
  客户端和服务端交互数据完毕后,开始通过四次挥手结束TCP会话连接。
  4.1. 理论
  
  第一次挥手:客户端 发送一个[FIN+ACK],表示自己没有数据要发送了,想断开连接,并进入FIN_WAIT_1状态(不能再发送数据到服务端,但能够发送控制信息ACK到服务端)。
  第二次挥手:服务端收到FIN后,知道不会再有数据从客户端传来,发送ACK进行确认,确认序号为收到序号+1(与SYN相同,一个FIN占用一个序号),服务端进入CLOSE_WAIT状态。
  第三次挥手:服务端发送FIN给对方,表示自己没有数据要发送了,服务端进入LAST_ACK状态,然后直接断开TCP会话的连接,释放相应的资源。
  第四次挥手:客户端收到了服务端对FIN的ACK后,进入FIN_WAIT2状态(等待服务端完成资源释放的一系列工作:然后释放你为创建这个连接所分配的资源,并通知我你关闭了); 客户端收到了服务端的FIN信令后,进入TIMED_WAIT状态,并发送ACK确认消息。客户端在TIMED_WAIT状态下,等待2MSL一段时间,没有数据到来的,就认为对面已经收到了自己发送的ACK并正确关闭了进入CLOSE状态,自己也断开了到服务端的TCP连接,释放所有资源。当服务端收到客户端的ACK回应后,会进入CLOSE状态,并关闭本端的会话接口,释放相应资源。
  TIME_WAIT状态持续2MSL(MSL是数据分节在网络中存活的最长时间)
  网络上比较主流的文章都说关闭TCP会话是四次挥手,但是实际上为了提高效率通常合并第二、三次的挥手,即三次挥手。下方中的抓包也证明了这一点
  4.2. 为什么需要四次挥手协议
  TCP协议是一种面向连接的、可靠的、基于字节流的传输层通信协议。TCP是全双工模式,需要两边的连接全部关闭,此TCP会话才算完全关闭,四次挥手使得TCP的全双工连接能够可靠的终止。另外TIMED_WAIT也使得连接终止后网络上残余的发送给该连接的数据被丢弃而不至于被新连接接收.
  下面根据客户端(10.240.89.99) 向 服务端(47.95.47.253) 发起关闭连接请求的抓包进行学习挥手协议
  
  4.3. 第一次握手
  第一次握手 客户端(10.240.80.99) 发送ACK ,通过FIN通知对方关闭连接
  包关键属性如下:
  ACK + FIN : 标志位
  seq = 2167 :已经发送的数据字节
  Ack = 14118 :已经收到的数据字节+SYN包
 
  4.4. 第二、三次握手
  第二、三次握手:服务端(47.95.47.253)关闭的连接,通过FIN通知对方关闭连接
  包关键属性如下:
  ACK + FIN : 标志位
  Seq = 14118:已经发送的数据字节
  Ack = 2168 :已经收到的数据字节+SYN包+ FIN包,Ack = 原Ack + 1, SYN标志位和FIN标志位也要占1位
  
  4.5. 第四次握手
  第四次握手客户端(10.240.80.99 )关闭连接,并发送ACK值和Ack确认号( Ack的值+1) 包关键属性如下:
  ACK : 标志位
  Seq = 2168:已经发送的数据字节
  Ack = 14119 :已经收到的数据字节+SYN包+ FIN包,Ack = 原Ack + 1, SYN标志位和FIN标志位也要占1位
  
  TCP/IP

      上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号