网站开发 翻译,wordpress商业授权,查看wordpress管理员,软件开发包含网站开发基于TCP协议的通讯流程1、TCP建立连接2、TCP断开连接3、TCP状态转换TCP状态解释#xff1a; SYN-RECVD#xff1a;再收到和发送一个连接请求后等待对方对连接请求的确认 ESTABLISHED#xff1a;代表一个打开的连接 FIN-WAIT-1#xff1a;等待远程TCP连接中断请求#xff0… 基于TCP协议的通讯流程1、TCP建立连接2、TCP断开连接3、TCP状态转换TCP状态解释 SYN-RECVD再收到和发送一个连接请求后等待对方对连接请求的确认 ESTABLISHED代表一个打开的连接 FIN-WAIT-1等待远程TCP连接中断请求或先前的连接中断请求的确认 FIN-WAIT-2从远程TCP等待连接中断请求 CLOSE-WAIT等待从本地用户发来的连接中断请求 CLOSING等待远程TCP对连接中断的确认 LAST-ACK等待原来的发向远程TCP的连接中断请求的确认 TIME-WAIT等待足够的时间以确保远程TCP接收到连接中断请求的确认 CLOSED没有任何连接状态 TIME_WAIT状态 从TCP状态迁移图可知只有首先调用close()发起主动关闭的一方才会进入TIME_WAIT状态而且是必须进入图中左 下角所示的3条状态迁移线最终均要进入该状态才能回到初始的CLOSED状态。 从图中还可看到进入TIME_WAIT状态的TCP连接需要经过2MSL才能回到初始状态其中MSL是指Max Segment Lifetime即数据包在网络中的最大生存时间。每种TCP协议的实现方法均要指定一个合适的MSL值如RFC1122给 出的建议值为2分钟又如Berkeley体系的TCP实现通常选择30秒作为MSL值。这意味着TIME_WAIT的典型持续时间为1-4分 钟。 TIME_WAIT状态存在的原因主要有两点 1为实现TCP这种全双工full-duplex连接的可靠释放 参考本文前面给出的TCP释放连接4次挥手示意图假设发起active close的一方图中为client发送的ACK4次交互 的最后一个包在网络中丢失那么由于TCP的重传机制执行passiveclose的一方图中为server需要重发其FIN在 该FIN到达clientclient是active close发起方之前client必须维护这条连接的状态尽管它已调用过close具 体而言就是这条TCP连接对应的local_ip, local_port资源不能被立即释放或重新分配。直到romete peer重发的FIN 达到client也重发ACK后该TCP连接才能恢复初始的CLOSED状态。如果activeclose方不进入TIME_WAIT以维护其连接状 态则当passive close方重发的FIN达到时active close方的TCP传输层会以RST包响应对方这会被对方认为有错误发 生而事实上这是正常的关闭连接过程并非异常。 2为使旧的数据包在网络因过期而消失 为说明这个问题我们先假设TCP协议中不存在TIME_WAIT状态的限制再假设当前有一条TCP连接(local_ip, local_port, remote_ip,remote_port)因某些原因我们先关闭接着很快以相同的四元组建立一条新连接。本文前面介绍过TCP连接由四元组唯一标识因此在我们假设的情况中TCP协议栈是无法区分前后两条TCP连接的不同的在它看来这根本就是同一条连接中间先释放再建立的过程对其来说是“感知”不到的。这样就可能发生这样的情况前一条TCP连接由local peer发送的数据到达remote peer后会被该remot peer的TCP传输层当做当前TCP连接的正常数据接收并向上传递至应用层而事实上在我们假设的场景下这些旧数据到达remote peer前旧连接已断开且一条由相同四元组构成的新TCP连接已建立因此这些旧数据是不应该被向上传递至应用层的从而引起数据错乱进而导致各种无法预知的诡异现象。作为一种可靠的传输协议TCP必须在协议层面考虑并避免这种情况的发生这正是TIME_WAIT状态存在的第2个原因。 具体而言local peer主动调用close后此时的TCP连接进入TIME_WAIT状态处于该状态下的TCP连接不能立即以同样的四元组建立新连接即发起active close的那方占用的local port在TIME_WAIT期间不能再被重新分配。由于TIME_WAIT状态持续时间为2MSL这样保证了旧TCP连接双工链路中的旧数据包均因过期超过MSL而消失此后就可以用相同的四元组建立一条新连接而不会发生前后两次连接数据错乱的情况。 另一比较深入的说法 TIME_WAIT状态的存在让4次握手关闭流程更加可靠4次握手的最后一个ACK是是由主动关闭方发送出去的若这个ACK丢失被动关闭方会再次发一个FIN过来而此时主动方已经认为断开链接收不到这个FIN被动方就会再次发送。若主动关闭方能够保持一个2MSL的TIME_WAIT状态则有更大的机会让丢失的ACK被再次发送出去。 主动关闭的过程TIME_WAIT1-TIME_WAIT 2-CLOSED被动关闭的过程CLOSE_WAIT-CLOSED 1、客户端是调用函数close()这时客户端会发送一个FIN给服务器。2、服务器收到FIN关闭套接字读通道并将自己状态设置为CLOSE_WAIT表示被动关闭并返回一个ACK给客户端。 3、客户端收到ACK关闭套接字写通道这是两次握手接下来服务器会调用close()1、服务器close()发送一个FIN到客户端。2、客户端收到FIN关闭读通道并将自己状态设置成TIME_WAIT发送一个ACK给服务器。3、服务器收到ACK关闭写通道并将自己状态设置为CLOSE。4、客户端等待两个最大数据传输时间然后将自己状态设置成CLOSED。TIME_WAIT状态的作用1、保证全双工通信可靠关闭如果不设置TIME_WAIT状态直接设置成CLOSED状态那么服务器得不到回复会一直发送FIN给客户端。2、保证这次连接的重复数据段从网络中消失。如果不设置那么最后一个回复的时候需要建立一个socket端口号可能跟现在的不一样服务器就会认为是另外的端口号发来的从而出现数据混乱。