读书笔记十二:TCP/IP详解之TCP连接的建立与终止
TCP连接的建立与终止
TCP连接的建立可以简单的称为三次握手,而连接的中止则可以叫做四次挥手。
建立连接协议
在TCP/IP协议中,TCP协议提供可靠的连接服务,采用3次握手建立一个连接。
- 第一次握手:建立连接时,客户端发送SYN包(syn=j)到服务器,并进入SYN_SEND状态,等待服务器确认;
- 第二次握手:服务器收到SYN包,必须确认客户的SYN(ack = j+1),同时自己也发送一个SYN包(syn=k),即SYN+ACK包,此时服务器进入SYN_RECV状态;
- 第三次握手:客户算收到服务器的SYN+ACK包,向服务器发送确认包ACK(ack= k+1),此包发送完毕后,客户端和服务器进入ESTABLELISHED状态,完成3次握手;
如没有第三次连接,假如A计算机选择了一条最长的路径发送建立连接请求数据包,但是由于路径长,所以时间较长,这个时候A计算机由于等待时间长,可能会再次发送一个数据包,此时这个数据包发送很快,且B计算机接收到后也发送了一个确认的数据包。过了一会远程的发送的建立连接请求的数据包,也到达了B计算机,则此时B计算机会再给A计算机发送一个确认信号的数据包,但是A计算机就不再确认,此时B计算机就处于等待状态,但是A计算机就不会搭理计算机B。这就造成了计算机B的资源浪费。
连接终止协议
终止一个连接需要进行4次握手,这是由TCP的半关闭造成的。
四次挥手:
第一次挥手:客户端向服务器发送FIN段(FIN=1),请求释放连接,等待服务器确认;
第二次挥手:服务器向客户发送ACK段(ACK=1);
第三次挥手:服务器向客户发送FIN段(FIN=1),请求释放连接,等待客户确认;
第四次挥手:客户向服务器发送ACK段,并等待2MSL时间后关闭连接,服务器收到该ACK后马上关闭连接;
TCP协议采用四次挥手进行断连的原因是为了确保断链过程的可靠,不会由于不可靠断连而破坏TCP的可靠传输。TCP协议的四次挥手断连是对称断连,要求两端都主动提出断连请求(发送FIN段),这样可以确保双方均能确认是否已收到对方的数据,确保可靠数据传输的目的。
客户端的状态是ESTABLISHD-->FIN_WAIT_1-->FIN_WAIT_2->TIME_WAIT-->CLOSED
服务器状态是ESTABLISHED-->CLOSE_WAIT-->LAST_ACK--->CLOSED
MSL最大生存时间,是任何TCP段被丢弃前在网络内存活的最长时间。原因是:第一,为了防止最后一段ACK丢失,会导致服务器重发FIN,这样在客户端真正释放连接前可以再次发送ACK段确保服务器尽快释放连接,第二,保证本地断点地址不被再次使用,防止上一次连接中的包,迷路后重新出现,影响新连接
1)为了保证客户端发送的最后一个ACK报文段能够达到服务器。 这个ACK报文段可能丢失,因而使处在LAST-ACK状态的服务器收不到确认。服务器会超时重传FIN+ACK报文段,客户端就能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重启计时器。最好,客户端和服务器都正常进入到CLOSED状态。如果客户端在TIME-WAIT状态不等待一段时间,而是再发送完ACK报文后立即释放连接,那么就无法收到服务器重传的FIN+ACK报文段,因而也不会再发送一次确认报文。这样,服务器就无法按照正常步骤进入CLOSED状态。
2)防止已失效的连接请求报文段出现在本连接中。客户端在发送完最后一个ACK确认报文段后,再经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。
第一次挥手:客户端向服务器发送FIN段(FIN=1),请求释放连接,等待服务器确认;
第二次挥手:服务器向客户发送ACK段(ACK=1);
第三次挥手:服务器向客户发送FIN段(FIN=1),请求释放连接,等待客户确认;
第四次挥手:客户向服务器发送ACK段,并等待2MSL时间后关闭连接,服务器收到该ACK后马上关闭连接;
TCP协议采用四次挥手进行断连的原因是为了确保断链过程的可靠,不会由于不可靠断连而破坏TCP的可靠传输。TCP协议的四次挥手断连是对称断连,要求两端都主动提出断连请求(发送FIN段),这样可以确保双方均能确认是否已收到对方的数据,确保可靠数据传输的目的。
客户端的状态是ESTABLISHD-->FIN_WAIT_1-->FIN_WAIT_2->TIME_WAIT-->CLOSED
服务器状态是ESTABLISHED-->CLOSE_WAIT-->LAST_ACK--->CLOSED
MSL最大生存时间,是任何TCP段被丢弃前在网络内存活的最长时间。原因是:第一,为了防止最后一段ACK丢失,会导致服务器重发FIN,这样在客户端真正释放连接前可以再次发送ACK段确保服务器尽快释放连接,第二,保证本地断点地址不被再次使用,防止上一次连接中的包,迷路后重新出现,影响新连接
1)为了保证客户端发送的最后一个ACK报文段能够达到服务器。 这个ACK报文段可能丢失,因而使处在LAST-ACK状态的服务器收不到确认。服务器会超时重传FIN+ACK报文段,客户端就能在2MSL时间内收到这个重传的FIN+ACK报文段,接着客户端重传一次确认,重启计时器。最好,客户端和服务器都正常进入到CLOSED状态。如果客户端在TIME-WAIT状态不等待一段时间,而是再发送完ACK报文后立即释放连接,那么就无法收到服务器重传的FIN+ACK报文段,因而也不会再发送一次确认报文。这样,服务器就无法按照正常步骤进入CLOSED状态。
2)防止已失效的连接请求报文段出现在本连接中。客户端在发送完最后一个ACK确认报文段后,再经过时间2MSL,就可以使本连接持续的时间内所产生的所有报文段都从网络中消失。这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。
TCP的状态变迁图
2MSL等待状态(TIME_WAIT状态)
MSL:报文段最大生存时间,它是任何报文段被丢弃前在网络内的最长时间。
当TCP执行一个主动关闭,并发回最后一个ACK之后,该连接必须在TIME_WAIT状态停留时间为2倍MSL,这样可以让TCP再次发送最后的ACK以防止这个ACK丢失(另一端超时并重发最后的FIN)。
FIN_WAIT_2状态
这就是著名的半关闭的状态了,客户端关闭了到服务器方向上的连接,还能接受服务器方向发送的数据。如果服务器一直不关闭服务器到客户端的TCP连接,客户端会一直处于FIN_WAIT_2状态,而服务器则一直处于WAIT_CLOSE状态,直到应用层来决定关闭这个状态。
RST报文段的作用
RST:TCP首部中的6个标志比特之一,表示重置连接、复位连接。一般说来,无论何时一个报文段发往基准的连接(referenced connection)出现错误,TCP都会发出一个复位报文段(这里提到的“基准的连接”是指由目的IP地址和目的端口号以及源IP地址和源端口号指明的连接。)
RST报文段能够中途释放一个连接,称为异常释放(当应用程序出现异常时发送RST报文段);RST报文段还能够检测并关闭半打开连接。
异常终止对于程序的优点:
(1)丢弃任何待发数据并立即发送复位报文段;
(2)RST的接收方会区分另一端是异常关闭还是正常关闭。
收到RST报文段表示另一端已经终止了连接,本机不会产生任何响应,而是直接终止该连接,并通知应用层连接复位。
需要注意的是RST报文段不会导致另一端产生任何响应,另一端根本不进行确认。收到RST的一方将终止该连接,并通知应用层连接复位。
3.检测半打开连接
如果一方已经关闭或异常终止连接而另一方却还不知道,我们将这样的TCP连接称为半打开(Half-Open)的。任何一端的主机异常都可能导致发生这种情况。只要不打算在半打开连接上传输数据,仍处于连接状态的一方就不会检测另一方已经出现异常。
半打开连接的另一个常见原因是当服务器主机突然掉电而不是正常的结束服务应用程序后再关机,服务器主机重启后,从客户向服务器发送另一行字符。由于服务器的TCP已经重新启动,它将丢失复位前连接的所有信息,因此它不知道数据报文段中提到的连接。TCP的处理原则是接收方以复位作为应答。
同时打开和同时关闭则是两种特殊的TCP状态,指连接双方同时执行主动打开或主动关闭,发生的概率很小。
在代码的世界尽情的翱翔吧!