关于TCP传输协议(面向连接篇) – 源码巴士

您所在的位置:网站首页 udp怎么实现可靠传输 关于TCP传输协议(面向连接篇) – 源码巴士

关于TCP传输协议(面向连接篇) – 源码巴士

#关于TCP传输协议(面向连接篇) – 源码巴士| 来源: 网络整理| 查看: 265

关于TCP传输协议(面向连接篇)

“ 此篇文章主要是想简单介绍一下TCP协议,大部分内容都是结合自己的理解,尽量用通俗的语言描述问题”

- 我理解的面向连接

在最开始学的时候我也不太能理解面向连接怎么理解,难是真的有一个东西在中间连接着两台不同的主机来实现网络通信吗?显然不是!其实,面向连接是通过要连接的两台主机分别在自己的主机上开辟一块区域,然后通过TCP协议来共同维护这两块区域,已实现网络传输的可靠性。所以,面向连接就是为了保证数据的可靠性。

这样说可能还不是很好理解,那么在对比一下面向无连接理解一下。UDP协议就是典型的无连接协议,在两台主机之间网络通信时,不需要知道目标主机ip和目标端口是否存在,可以按照定义的ip和端口直接发送到网络中,而面向连接则是先根据给定的目标ip和端口号发送到网络中一些消息来确认目标主机是否存在,如果不存在则不能完成接下来的网络通信。

所以,面向连接是需要先建立连接才能进行网络通信的,建立连接就是确定对方存在并协商好一些控制量来确保接下来的通信是可靠的。

下面先来介绍一下TCP协议著名的TCP三次握手和四次挥手三次握手 在建立连接前,接收连接的一端一定是事先处于监听状态,其他主机才能连接。在这里插入图片描述 首先客户端给服务器发送建立连接报文,并携带一个系统随机的序列号(seq);服务器接收到此报文,并发送一个建立连接+确认报文,报文中带有系统随机的序列号(seq)和确认序列号(ack),客户端收到此报文,并发送一个确认报文,报文中带有序列号和确认序列号。

第一次:client发送请求连接,server收到client发送的请求连接,server确认对方发送正常,自己接收正常;

第二次:server发送确认+请求连接;client收到server请求连接,确认自己发送正常,接收正常;对方发送正常,接收正常;client发送确认包;

第三次:server收到确认包,确认自己发送正常,对方接收正常。

通过这三次网络通信,双方就都能互相确认双方的发送和接收数据都是正常的,这样网络连接就完成了。

四次挥手 因为TCP是面向连接的,所以通信结束后要断开连接,目的是释放双方为此次连接所创建的资源,四次挥手就是断开连接过程。

正常断开连接的过程一般都是客户端发出的,所以这里就按照客户端主动断开连接来聊。(服务器主动断开连接过程和这个一样)在这里插入图片描述

首先,客户端主动断开连接,发送一个结束报文段,服务器收到此报文,并发送一个确认报文,客户端收到此报文,然后再发送一个确认报文段,客户端接收到此报文,并发送一个确认报文段,之后进入TIME_WAIT状态等待2MSL时间,时间过后客户端关闭,服务器收到客户端的确认报文段则关闭。

问题1:为什么是连接是三次握手,断开确是四次挥手?

对比两张图可知,问题就出在了第二次握手和第二、三次挥手,第二次握手是将连接请求报和确认报文合并到一起,而四次挥手则是将这两个报文分开发送的,主要的原因在于在刚开始建立连接的时候,双方是没有数据通信的,而在断开连接的时候有可能被动断开的一方还有数据没有发送完,所以要先发送一个确认报文,让客户端知道对方已经收到结束报文,客户端则可以进入FIN_WAIT_1等待并接收数据状态,等到服务器发送完所有数据,再发送一个结束报文段。如果服务器没有数据要发送,并且是捎带应答机制,那么是有可能三次挥手的(至于为什么是可能,其实有些细节想到了就行,至于是三次还是四次,也不差一次,理解到位就可以了)。

问题2:主动断开连接的一方为什么要等待2MSL时长?

原因有二:一是确保服务器收到最后发送的确认报文段,服务器关闭。二是如果当前网络波动比较大,可能会有之前服务器发送的数据延时到达,所以要等到2MSL时长保证那些数据能够到达。

最后,这个问题我还想细聊一下,关于第一个原因,如何确保服务器收到最后一个报文段?客户端在等待的这段时间,如果再次收到了服务器发来的断开连接报文,说明服务器没有收到最后一个确认报,触发了TCP的重传机制,这时客户端重新收到断开连接包并重新发送确认包和重新计时2MSL。如果有些兄弟钻牛角尖,就会说那如果服务器重新传的断开连接包客户端没有收到怎么办,那服务器对应的连接就变成了孤儿连接,在linux系统中,这些孤儿连接又系统内核接管,并有两种处理方案,一种是设置最多孤儿连接数,二是设置孤儿连接的存活时长。 关于第二个原因,确保数据都能被客户端收到,如果收不到会怎样? 设置这样一个场景,客户端断开连接,服务器没断开并且在发送数据,而此时客户端重新开启了一个客户端,此时客户端就会收到上一个客户端没接收完的数据,引起程序错误,但实际情况中,这种情况几乎不可能出现,因为客户端开启时的端口号是系统随机分配的,不会冲突,所以之前的网络包根本不会到新的客户端上,都不会发生为啥还要有这种情况呢?因为我们假设的是客户端主动断开的连接,如果是服务器主动断开连接呢,并且没有2MSL等待,这种情况下再次重新登录服务器,服务器每次登录时端口号都是固定的,是不是就会收到之前的网络包了。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3