Wireshark抓包分析三次握手四次挥手

根据在8.3.3节中介绍的协议的封包格式,再将Wireshark捕获的TCP包中的各个字段对应起来,更直观地看到TCP的通信过程。本次抓包分析使用8.1.5节中的TCP编程程序,在ubuntu系统直接本地运行客户端与服务器端,并抓包成功。本节将通过抓包主要分析关于TCP的三次握手与四次挥手的情况。
先查询三次握手,下图8.33中的3条数据包是一次TCP建立连接的过程。
Wireshark抓包分析三次握手四次挥手_第1张图片
图8.33 三次握手数据包
第一次握手,客户端发送一个TCP,标志位(SYN)为1,序列号seq(Sequence number)为0(假设此seq为i,i==0),源端口号为54918,目的端口号为8080。代表客户端请求建立连接,如下图8.34所示。可以看出这里的Flags与tcp封包头信息(参照图8.7)中的保留位(4位)和控制位(8位)一一对应。一共12位,Flags值为0x002,其中SYN位在低位第二位,因此SYN值为1。
Wireshark抓包分析三次握手四次挥手_第2张图片

第二次握手,服务器向客户端返回一个数据包,标志位SYN为1,建立回复确认序列号ACK(Acknowledgement Number)设置为i+1,即为1。同时会选选取一个序列号为0(假设为j,j==0)源端口号为8080,目的端口号为54918。如下图8.35所示。
Wireshark抓包分析三次握手四次挥手_第3张图片
图8.35 第二次握手数据包信息
第三次握手,客户端接收到服务器发送的数据包后检查其确认序列号(Acknowledgement number)是否正确,即i+1(为1)。若正确,客户端会向服务器发送一个数据包,其SYN为0,确认序列号ACK(Acknowledgement)为服务器端发送的序列号j+1(为1),和本次需要发送的序列号为i+1(为1)。至此,一次TCP连接就此建立,则可以开始传输数据。如下图8.36所示。
Wireshark抓包分析三次握手四次挥手_第4张图片
图8.36 第三次握手数据包信息
根据上述解析,可以清楚地看到TCP三次握手的具体信息参数。同时在此基础上,可以更好的理解三次握手的过程及缘由。TCP客户端之所以最后要发送一次确认,通过三次握手建立连接,主要是为了防止已经失效的连接请求报文又发送到了服务器,再次建立TCP连接产生错误。
假设在这样一个场景中,客户端发送请求报文后,在网络中的某个节点滞留一段时间,TCP客户端迟迟没有收到服务器的确认报文会重新向服务器发送这条报文,经过两次握手建立连接之后, 传输数据,关闭连接。而之前滞留的请求报文到达服务器之后也会与服务器再次建立连接。如果是三次握手,客户端就不会发出确认报文,服务器收不到确认报文,就不会建立连接,减少不必要的错误。
TCP断开连接是通过发送FIN报文,来告诉对方数据已经发送完毕,可以释放连接。 其Wireshark抓包列表如下图8.37所示。
Wireshark抓包分析三次握手四次挥手_第5张图片
图8.37 三次握手、四次挥手数据包列表
本次示例使用的是在一个ubuntu系统,运行服务器与客户端进行通信。因此通信使用的地址为本地主机地址(环回地址)。由于监听本地环回,速度太快,导致服务器收到FIN以后,调用close的时候,会清除socket缓存区的ACK应答,这将导致无法捕获四次挥手的情况。因此需要在服务器收到FIN之后,休眠一点时间再调用close,则可以通过Wireshark看到完整的四次挥手消息。
如上图8.37所示。第一次挥手,当客户端的数据发送完毕之后,会向服务器端发送一个FIN(==257)的报文,用来关闭客户端到服务器端的数据传送。
第二次挥手,服务器端收到FIN后,发送一个ACK给客户端,确认序号为FIN(==257)+1。此时服务器端进入关闭等待状态。
第三次挥手,服务器端发送一个FIN(==129),用来关闭服务器端到客户端的数据传送。
第四次挥手,客户端收到FIN之后,接着发送一个ACK给服务器端,确认序列号为收到序列号(==129)+1,此时服务器进入关闭状态,完成四次挥手。
TCP断开连接之所以采用四次挥手,则是因为服务器端在监听状态下,收到连接请求SYN报文后,把ACK和SYN放在一个报文里发送给客户端。而关闭连接时,当收到对方的FIN报文之后,仅仅表示对方不再发送数据了但是还能接收数据。此时己方也有可能没有将全部数据发送给对方,因此己方可以发送完剩余数据之后,再发送FIN报文给对方表示同意关闭连接。因此,己方ACK和FIN一般都会分开发送。

你可能感兴趣的:(Linux系统编程)