传输层(二)——TCP的连接控制机制

传输层(二)

TCP的连接控制机制

传输层(二)——TCP的连接控制机制_第1张图片

服务器状态转化:
1.CLOSED -> LISTEN:服务器创建监听套接字后进入LISTEN状态,等待客户端建立连接;
2.LISTEN -> SYN_RCVD:当监听到连接请求(SYN),就将该连接放入内核等待队列,并给客户端发送ACK确认;
3.SYN_RCVD -> ESTABLISHED:当再次收到客户端的ACK确认报文,就建立一个新连接,进入WSTABLISHED状态,此时可以读写数据;
4.ESTABLISHED -> CLOSE_WAIT:当客户端主动断开连接,服务器收到FIN结束报文段,此时服务器发送ACK确认报文,并进入CLOSE_WAIT状态;
5.CLOSE_WAIT -> LAST_ACK:处理完之前的数据,服务器就调用close关闭连接,并发送FIN结束报文段,进入LAST_ACK状态等待客户端最后一个ACK确认;
6.LAST_ACK -> CLOSED:收到了客户端对结束报文段的ACK确认,彻底关闭连接。

客户端状态转化:
1.CLOSED ->SYN_SENT:开始connect,向服务器发送同步报文段;
2.SYN_SENT -> ESTABLISHED:收到了服务器的同步报文段和ACK确认,则客户端认为连接建立好,此时进入ESTABLISHED状态,可以读写数据;
如果三次握手时最后一次报文丢失,客户端会认为建立好了连接,然而服务器认为没有建立好连接,此时服务器给客户端一个RST响应,告诉客户端并没有建立连接。当客户端收到该响应:应重新建立连接或关闭老连接。(复位报文段)

3.ESTABLISHED -> FINWAIT 1:客户端主动调用close时,向服务器发送结束报文段,并进入FINWAIT 1状态;
4.FINWAIT 1 -> FINWAIT 2:当收到服务器对结束报文的ACK确认,客户端进入FINWAIT 2状态,等待服务器的FIN结束报文段;
5.FINWAIT 2 -> TIME_WAIT:当客户端收到服务器的结束报文段,会进入TIME_WAIT状态,并向服务器发送最后一次ACK确认了结束报文;
6.TIME_WAIT -> CLOSED:客户端会等待2MSL(两个报文生存最大时间),才进入CLOSED彻底关闭连接。

三次握手的原因

如果是两次握手,当服务器收到客户端发送的SYN同步报文段之后则认为连接建立,然后会维护该连接,将该连接组织管理起来,进入ESTABLISHED状态,并发送ACK报文段给客户端;
客户端收到ACK后才会进入ESTABLISHED状态建立连接。如果ACK丢包,客户端会认为连接没有建立,而重新向服务器发送重复的SYN报文段,服务器接收后会再次建立该连接,而维护连接是消耗资源的,如果ACK一直丢失,客户端会一直发送SYN,服务器就会建立很多相同的无效的连接,从而使服务器资源浪费,使服务器受到影响。
还有另外一个原因:客户端发送第一个报文,证明了客户端发送能力没问题;服务器发送第二个报文,证明服务器的接受不了和发送能力没问题;但只有发送了第三个报文,才能证明客户端发送能力没问题。

如果是三次握手,当客户端收到来自服务器的SYN+ACK后,会进入ESTABLISHED状态,并建立和维护该连接;
客户端会发送ACK确认报文,服务器收到了才会进入ESTABLISHED状态并建立维护连接;
即使最后一次ACK‘丢失,客户端认为建立好了连接,然而服务器认为没有建立好连接,此时服务器给客户端一个RST响应,告诉客户端并没有建立连接。当客户端收到该响应:应重新建立连接或关闭老连接。虽然客户端会建立一些无效连接,会受到影响,但是服务器并没有受到影响,从而保证了服务器的安全。同时客户端虽然受到了影响,但随后会重新建立连接,所以会减小影响。

总结一下:
1.两次握手可能会使服务器建立很多无效连接,浪费资源;
2.虽然三次握手可能会使客户端受影响,但随后会重建;
3.三次就够了,不需要更多次握手。四次握手跟两次握手是一样的。

四次分手的原因

分手是双方的事,必须要双方都同意

TIME_WAIT的原因

1.等待两个报文的最大生存时间,就能保证两个传输方向上未被接收或迟到的报文段消散;
2.保证最后一次ACK可靠到达(因为最后一次ACK可能丢失,主动断开连接的一方要等待:如果对端重发了FIN,则最后一次ACK丢失;若没收到,则发送成功。)
————————————————
————————————————
版权声明:本文为CSDN博主「_来信」的原创文章
原文链接:https://blog.csdn.net/han8040laixin/article/details/81283399

同时打开,同时关闭,半打开

TCP半打开连接

如果一方已经关闭或者异常终止连接而另外一方却还不知道,这样的连接就称为半打开连接(Half open connection)。处于半打开的连接,如果双方不进行数据通信,是发现不了问题的,只有在通信是才真正的察觉到这个连接已经处于半打开状态,如果双方不传输数据的话,仍处于连接状态的一方就不会检测另外一方已经出现异常

半打开连接的一个常见的原因是客户端或者服务器突然掉电而不是正常的结束应用程序后再关机,这样即使重新启动后,原来的连接信息已经消失了,对端仍然保持半打开状态,如果需要发数据的话,这边收到之后 其实发现这个连接并不存在了,就会回复RST包告知,这个时候就需要重新建立连接了!

接下来使用SSH协议复制一下这个场景:

  1. 打开SSH Secure Shell Client,然后登陆到远程的Linux服务器 192.168.1.104 DST PORT 22

  2. 建立连接成功,可以在client进行linux操作

  3. 需要模拟服务器出现异常,先关掉网卡,然后关机(关掉网卡,为了避免关机时服务器主动退出发送FIN包)

  4. 这样服务器已经出现异常关闭,但是此时Client端并没有任何察觉,这个时候连接已经处于半打开状况

  5. 重新打开服务器

  6. 操作客户端,发现已经出现了异常,无法通信,并提示重新连接, 这个时候实际上客户端发送的包被服务器给RST了,因为之前的连接信息已经丢失了

  7. 重新连接之后可以正常的进行通信

同时打开

两个应用程序同时彼此执行主动打开的情况,2端的端口需要一致,这就需要双方都熟知端口,这种情况发生的概率很小 ,这里简单的介绍一下

场景:
传输层(二)——TCP的连接控制机制_第2张图片

  1. PC1的应用程序使用端口7777 与PC2的端口8888 执行主动打开

  2. PC2的应用程序使用端口8888 与PC1的端口7777 执行主动打开

  3. SYN包同时打开对端,这种情况即为同时打开

TCP中,对于同时打开它仅建立一条连接而不是两条连接,状态变迁图如下:同时发送SYN包,然后收到进行确认直接进入ESTABLISHED状态,可以看到同时打开需要连接建立需要4个报文段,比三次握手多一次!

同时关闭

有同时打开,理所应当的也有同时关闭的场景,TCP协议也允许同时关闭。状态变化可以看到下图了,同时发送FIN包,两端同时执行主动关闭,进入FIN_WAIT_1的状态,从FIN_WAIT_1状态收到FIN包的时候进入CLOSING状态,然后回复ACK,进入TIME_WAIT状态。

传输层(二)——TCP的连接控制机制_第3张图片
————————————————
版权声明:本文为CSDN博主「CQ小子」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/wdscq1234/article/details/52422657

你可能感兴趣的:(计算机网络)