TCP的连接过程

在tcp协议中,主动发起连接请求的为客户端,被动连接的为服务端。初次连接有三次握手,即三个报文的交换。释放连接时有四次挥手,即4个报文的交换。 三次握手的过程。有A客户端、B服务端。B服务器进程首先创建传输模块,准备接收客户端的连接请求。这时服务端处于listen监听状态。A客户端进程先创建传输模块,然后向服务端发送连接请求报文。B服务端收到报文后如同意连接,将发送一个应答报文。客户端A收到报文后向服务端B发送一个确认报文。致此连接建立。

整个过程是怎么样的呢?

逻辑上我们可以这么理解建立链接的过程,有两台主机A和B:

  1. SYN:seq=X;
    • A的TCP程序,为这个链接分配一个端口(设为9090)。
    • 同时 逻辑上 的将TCP连接的状态设置为:正在连接。(通过在链接状态表中添加一条记录,记录中状态为:正在连接)
    • 同时,随机生成一个初始序列号X,生成一个TCP包,将初始化序列号X设置为TCP中的序列号,发送给主机B。
  2. SYN:seq=Y ACK:ack=X+1;
    • B上TCP程序收到该数据包,查询9091端口状态,如果可以链接。
    • 同样的,在逻辑上的将TCP连接的状态设置为:正在连接
    • 同时,随机生成一个初始化序列号Y,根据接收的序列号X,生成应答号X+1,生成一个TCP包,将序列号和应答号分别设置到TCP包头中,将TCP数据包发给主机A。
  3. SYN:seq=X+1 ACK:ack=Y+1.
    • A上的TCP程序接收到数据包,查询9090端口状态。
    • 根据收到的SYN:seq=Y;ACK:ack=X+1; 封装一个TCP包 SYN:seq=x+1;ACK:ack=Y+1;发送给主机B。同时,TCP程序将链接状态表中该条记录状态设置为已连接。
    • 主机B收到数据包,TCP程序将链接状态表中该条记录状态设置为已连接。

至此,一个TCP链接建立(三次握手)完成。
我们可以看到:

  1. 传送的都是IP数据包,其实只是将收到的数据包交给TCP程序处理
  2. 链接状态,只是TCP程序中的一个逻辑状态

三次握手的目的是什么?

TCP是面向链接的,在面向链接的环境中,开始传输数据之前,在两个中端之间必须先建立一个链接。建立链接的过程可以确保通信双方在发送应用程序数据包之前,都已经准备好了传送和接收数据。并且使通信双方统一了初始化序列号。

为什么有3次握手?

  1. 正常情况
    client发送了连接请求,但是请求报文因为种种原因丢失而未确认。于是A超时重传,再一次发送请求连接报文。server收到了,然后再发送请求确认报文,并最终完成client与server的连接。数据传输结束后,释放连接。这个过程中,client一共发送了两个请求连接报文段,第一个丢失,第二个到达server。
  2. 异常情况
    在网络不好的情况下,client发送一个请求连接报文,然后超时没有收到服务器应答后,再次发送一个请求连接报文,这时突然关闭了连接。
    然后服务器收到了请求连接的报文,发送一个应答报文后建立了连接,但因为客户端已经关闭了连接,所以肯定不会像服务器发送数据,这就导致资源被浪费了。

采用三次握手的办法可以防止上述现象发生。

四次挥手

  1. Client发送FIN后,进入终止等待状态,seq=m;此时Client不再像Server发送数据,比如电话的音频数据,视频会议的视频数据。
  2. Server收到Client连接释放报文段后,就立即给Client发送确认报文,ack=m+1;此时Server还会向Client发送数据包。
  3. 如果Server没有数据报发送给Client,开始第三次挥手。Server向Client发送FIN报文,seq=n;
  4. Client回复Server关闭请求,ack=n+1;然后客户端进入TIME_WAIT状态,此时TCP连接还没有释放。但Server收到回复后关闭连接。Client经过2MSL后依然没有收到Server的回复则证明其连接已被关闭,因此Client关闭连接。

为什么是 2MSL?

MSL是最大的报文生存时间,报文超过这个时间将被丢弃。这个是由时间等待计时器设置的。

  1. 理由一
    • 在Client发送出最后的ACK回复,但该ACK可能丢失。Server如果没有收到ACK,将不断重复发送FIN片段。所以Client不能立即关闭,它必须确认Server接收到了该ACK。Client会在发送出ACK之后进入到TIME_WAIT状态。Client会设置一个计时器,等待2MSL的时间。如果在该时间内再次收到FIN,那么Client会重发ACK并再次等待2MSL。所谓的2MSL是两倍的MSL(Maximum Segment Lifetime)。MSL指一个片段在网络中最大的存活时间,2MSL就是一个发送和一个回复所需的最大时间。如果直到2MSL,Client都没有再次收到FIN,那么Client推断ACK已经被成功接收,则结束TCP连接。
  2. 理由二
    • client再发送完最后一个报文端ACK之后,再经过2MSL的时间,就可以是本次连接持续时间内的所有产生的报文段都消失,这样下一次连接中就不会出现旧的请求连接报文段。

为什么是四次挥手?

因为Client发送FIN关闭报文时表示Client没有数据要向Server发送了,但Server收到FIN报文时可能还有数据没有发送完,所以只能发送一个ACK回复收到了。
等发送完数据再向Client发送FIN报文请求关闭。

参考文章

  1. https://www.cnblogs.com/echoooo/p/15796535.html
posted @ 2023-06-14 13:20  Ysun_top  阅读(145)  评论(0编辑  收藏  举报