tcp协议格式
tcp三次握手过程
1.client端向server端发送一个SYN(连接请求)的报文,其中包含了一个初始序列号和一个窗口大小(主要是为了告诉对方自己的接受能力是多大);
2.服务器收到客户端发送的SYN报文后,也同样向对方发送一个SYN,ACK的报文,还有一个窗口大小(表示服务器上用来存储来自客户端数据多少的一个能力);
3,客户端收到服务器端返回的SYN和ACK之后,向服务器发送一个确认号+1和序列号+1的ACK报文。
如图所示:
为什么要三次握手?
在谢希仁的《计算机网络》一书中是这样讲的。“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送数据。但server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。
总结:
三次握手的目的是为了确保通信的建立,如果采用两次握手,client发送请求之后,server端同意之后就会认为通信已经建立好了,开始发送数据,但是如果确认报文在通信过程中丢失了,那么client端认为通信没有建立成功,那么就会忽略server,但是server在发送报文超时之后,又会进行超时重传,进而造成死锁。
为什么不采用四次握手建立通信?
在上图中我们会发现在第三次握手的时候有可能失败,在第三次握手之后,客户端就会认为通信建立好了,但是服务器端有可能会收不到确认报文,导致通信失败,但是这影响不大,因为这只影响了一个client端,相对于两次握手,如果失败影响的是所有的client,三次握手就可以解决问题,四次握手显得多余了。
为什么要四次挥手?
四次挥手过程详解图
为什么主动断开连接的一方会进入TIME_WAIT?
TIME_WAIT含义: 表示收到了对方的FIN报文,并发送出了ACK报文,就等2MSL后即可回到CLOSED可用状态了。如果FIN_WAIT_1状态下,收到了对方同时带FIN标志和ACK标志的报文时,可以直接进入到TIME_WAIT状态,而无须经过FIN_WAIT_2状态。
MSL是最长报文长度,在RFC793建议设为2分钟,2MSL就是4分钟。
这里,为什么A要等待这个时间之后才能断开连接呢?
1、为了保证客户端发送的最后一个ACK报文段能够到达服务器。因为这个ACK有可能丢失,从而导致处在LAST-ACK状态的服务器收不到对FIN-ACK的确认报文。服务器会超时重传这个FIN-ACK,接着客户端再重传一次确认,重新启动时间等待计时器。最后客户端和服务器都能正常的关闭。假设客户端不等待2MSL,而是在发送完ACK之后直接释放关闭,一但这个ACK丢失的话,服务器就无法正常的进入关闭连接状态。
2、他还可以防止已失效的报文段。客户端在发送最后一个ACK之后,再经过经过2MSL,就可以使本链接持续时间内所产生的所有报文段都从网络中消失。从保证在关闭连接后不会有还在网络中滞留的报文段去骚扰服务器。