【Android每日一问】TCP/IP协议三次握手与四次挥手

277 阅读5分钟

三次握手

  • TCP 提供面向有连接的通信传输。面向有连接是指在数据通信开始之前先做好两端之间的准备工作。
  • 所谓三次握手是指建立一个 TCP 连接时需要客户端和服务器端总共发送三个包以确认连接的建立。在socket编程中,这一过程由客户端执行connect来触发。

下面来看看三次握手的流程图(图片来自网络):

三次握手.jpeg

SYN:同步序列编号(Synchronize Sequence Numbers)

  • 第一次握手,客户端将标识位SYN设为1,随机生成一个seq=J,并将该数据包发送给服务端,客户端进入SYN_SENT状态,等待服务器端确认。
  • 第二次握手,服务端收到客户端发送的数据包,通过标识位SYN=1知道客户端在请求建立连接,服务端将SYN和ACK都置为1,ack=J+1,并随机生成一个seq=K,并将该数据包发送给客户端以确认连接请求,服务端进入SYN_RCVD(半开连接)状态。
  • 第三次握手,客户端收到服务端发送的数据包,检查ACK是否为1,seq是否为J+1,如果正确则将ACK置为1,ack=K+1,并将数据包发送给服务端,服务端检查ack是否为K+1,如果正确则建立连接成功,服务器和客户端进入ESTABLISHED状态,完成三次握手,随后客户端和服务端就可以正常的开始进行数据传输了。

四次挥手

全双工(Full Duplex)是通讯传输的一个术语。通信允许数据在两个方向上同时传输,它在能力上相当于两个单工通信方式的结合。全双工指可以同时(瞬时)进行信号的双向传输(A→B且B→A)。指A→B的同时B→A,是瞬时同步的。

  • 四次挥手即终止TCP连接,就是指断开一个TCP连接时,需要客户端和服务端总共发送4个包以确认连接的断开。在socket编程中,这一过程由客户端或服务端任一方执行close来触发。

  • 由于TCP连接是全双工的,因此,每个方向都必须要单独进行关闭,这一原则是当一方完成数据发送任务后,发送一个FIN来终止这一方向的连接,收到一个FIN只是意味着这一方向上没有数据流动了,即不会再收到数据了,但是在这个TCP连接上仍然能够发送数据,直到这一方向也发送了FIN。首先进行关闭的一方将执行主动关闭,而另一方则执行被动关闭。

下面来看看四次挥手的流程图(图片来自网络):

四次挥手.jpeg

  • 中断连接端可以是客户端,也可以是服务器端。
  • 第一次挥手,客户端发送一个FIN=M,用来关闭客户端到服务器端的数据传送,客户端进入FIN_WAIT_1状态。意思是说"我客户端没有数据要发给你了",但是如果你服务器端还有数据没有发送完成,则不必急着关闭连接,可以继续发送数据。
  • 第二次挥手,服务器端收到FIN后,先发送ack=M+1,告诉客户端,你的请求我收到了,但是我还没准备好,请继续你等我的消息。这个时候客户端就进入FIN_WAIT_2 状态,继续等待服务器端的FIN报文。
  • 第三次挥手,当服务器端确定数据已发送完成,则向客户端发送FIN=N报文,告诉客户端,好了,我这边数据发完了,准备好关闭连接了。服务器端进入LAST_ACK状态。
  • 第四次握手,客户端收到FIN=N报文后,就知道可以关闭连接了,但是他还是不相信网络,怕服务器端不知道要关闭,所以发送ack=N+1后进入TIME_WAIT状态,如果服务端没有收到ACK则可以重传。服务器端收到ACK后,就知道可以断开连接了。客户端等待了2MSL后依然没有收到回复,则证明服务器端已正常关闭,那好,我客户端也可以关闭连接了。最终完成了四次握手。

MSL是Maximum Segment Lifetime英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。

上面是一方主动关闭,另一方被动关闭的情况,实际中还会出现同时发起主动关闭的情况。

如下图:

同时挥手.jpeg

为什么是三次握手而不是两次或是四次?

  • 三次握手是保证连接的最少次数。
  • 如果是两次连接:不能有效防止洪范攻击,没有半连接队列,无法连接数量进行控制;假定当前网络状况不佳,A向B发送了SYN请求连接,此时因网络原因阻塞造成超时。A重发SYN,B收到后建立起连接并传输数据后关闭,此时之前阻塞的SYN再次到达B,B会以为A又要建立连接。

洪泛攻击,在短时间内向目标系统发送大量的虚假请求的攻击方式.

为什么是四次挥手?

  • TCP协议是一个全双工协议,当收发双方中一方关闭了连接,进入半双工状态,仍能向对方发送数据。