TCP握手与分手

TCP全名Tranmission Control Protocol,是一种面向连接的、可靠的、基于字节流传输层通信协议,由IETFRFC 793定义。TCP主要解决了UDP通信数据传输不可靠问题,即建立在不可靠通讯的基础之上,并辅之以自动窗口大小、重传、拥塞控制等机制。建立连接和断开连接,本质上是TCP的状态位不停变化,在不同的连接状态下进行数据操作。

其中,建立连接和断开连接是资源能正确使用和释放的前提,分为三次握手和四次分手,那么为什么是三次和四次这样的一种形式,而不是其他形式?本文将针对此问题,进行详细分析。下图来自WikiPedia TCP

TCP建立连接

  1. 服务器处于监听状态,客户端发起连接请求:SYN=x
  2. 服务端确认到SYN后,返回ACK=x+1,并向客户端发起SYN=y请求
  3. 客户端收到ACK和SYN,并向服务端返回ACK=y+1
  4. 连接建立

那为什么是三次握手呢,而不是四次或者两次,甚至更多?

【问题1】为什么不是两次?

TCP是建立在不可靠的数据通讯上,即面向无连接的UDP,若不进行互相确认就进行通讯,双方可能都收不到,直接丢包。平时打电话的时候就是很好的例子,只有双方都确认能听到声音了,才进行下一步的交谈。

【问题2】为什么不是四次或更多次?

假设确实是四次或更多次,从定义上说,主要在于对ACK包的确认,即需要确认对方收到了ACK包。在第三步后,即客户端向服务端发送ACK=y+1后,服务端为了表明收到了ACK,再向客户端返回ACK=y+2,客户端收到ACK,再向服务端返回ACK=y+3,...以此类推,为了ACK而ACK,无穷无尽,这样永远也建立不了连接。

TCP断开连接

  1. TCP在已经建立连接的基础上,客户端发起FIN=x请求;
  2. 服务端收到FIN=x,返回ACK=x+1,并使服务端进入不接收数据的状态;
  3. 等待服务端发送完所有数据后,服务端发送FIN=y;
  4. 客户端接收到FIN包,返回ACK=y+1;
  5. 断开连接。


【问题1】为什么连接的时候是三次握手,关闭的时候却是四次握手?
因为当服务端收到客户端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当服务端收到FIN报文时,因数据没发送完,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉客户端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送,故需要四步握手。

在做了斯坦福CS144课程作业有后感,这是另一种解释:TCP通讯为全双工通信,即能同时进行接收和发送,数据的流通方式主要通过操作系统API,即从网卡中获取数据或发送数据,发送和接收分为两条流水线。如下图所示,一方发送数据,另一方接收数据。

数据在网络中的展现像流水线一样,只要有数据,延绵不绝。当服务器还有数据发送,而此时客户端发起FIN请求,说明客户端不发数据了,服务器收到后将接收数据的流水线关闭,但因服务器还要发送数据,不能关闭服务器的发送流水线,需等都发完后再关闭。状态变更未下图所示。

等服务端发完所有数据,由服务端发送FIN后, 两者的连接才会进入新的状态,最后进入关闭状态。

【问题2】若运行过程中,有一方突然长时间掉线,如何处理?

和断开连接没关系,属于TCP机制的一部分。因TCP超过一定重传次数后,TCP状态直接至为RST,此时处于连接重置状态,数据接收和发送都不可用。


Wireshark关于TCP建立和断开实例

这里以向腾讯IP发起TCP连接为例,IP和端口:125.39.52.26:443。

1. 建立连接的数据包样式

过程1:建立TCP请求,发起SYN

过程2:服务端返回SYN+ACK

过程3:客户端返回ACK

2. 断开连接的数据包样式

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Linux TCP握手时间可以分为三个阶段:建立连接、数据传输和关闭连接。 首先是建立连接的握手过程。在客户端想要与服务器建立TCP连接时,它会发送一个SYN(synchronize)报文给服务器,并进入SYN_SENT状态。服务器接收到SYN报文后,会发送一个SYN-ACK(synchronize-acknowledge)报文作为响应,并进入SYN_RECV状态。最后,客户端收到SYN-ACK报文后,发送一个ACK(acknowledge)报文给服务器,确认连接建立。整个握手过程耗时通常为1个RTT(Round-Trip Time)。 接下来是数据传输阶段。一旦建立了连接,客户端和服务器可以开始进行数据传输。TCP使用滑动窗口协议来控制发送和接收缓冲区的大小,以便进行流量控制和拥塞控制。在这个阶段,具体的时间取决于数据传输的大小和网络状况。同时,为了保证数据的可靠传输,TCP还会进行数据的分段与重组,因此可能会有一定的时间延迟。 最后是关闭连接的握手过程。当客户端或服务器想要关闭连接时,它会发送一个FIN(finish)报文给对方,并进入FIN_WAIT状态。接收到FIN报文的一方会发送一个ACK报文作为回应,并进入CLOSE_WAIT状态。当另一方收到ACK报文后,会发送一个FIN报文作为确认,并进入LAST_ACK状态。最后,接收到确认的一方会发送一个ACK报文来关闭连接。整个关闭过程通常需要1个RTT的时间。 总之,Linux TCP握手时间取决于网络延迟、拥塞控制和数据传输的大小。这些因素都可能导致握手过程的时间延长。同时,根据具体的应用场景和需求,还可以通过调整TCP的参数来优化握手时间。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值