1.TCP传输层的三次握手过程
从图中可以看出,当客户端调用connect时,触发了连接请求,向服务器发送了SYN J包,这时connect进入阻塞状态;服务器监听到连接请求,即收到SYN J包,调用accept函数接收请求向客户端发送SYN K ,ACK J+1,这时accept进入阻塞状态;客户端收到服务器的SYN K ,ACK J+1之后,这时connect返回,并对SYN K进行确认;服务器收到ACK K+1时,accept返回,至此三次握手完毕,连接建立。
总结:客户端的connect在三次握手的第二个次返回,而服务器端的accept在三次握手的第三次返回。
2.TCP传输层的四次挥手过程
图示过程如下:
某个应用进程首先调用close主动关闭连接,这时TCP发送一个FIN M;
另一端接收到FIN M之后,执行被动关闭,对这个FIN进行确认。它的接收也作为文件结束符传递给应用进程,因为FIN的接收意味着应用进程在相应的连接上再也接收不到额外数据;
一段时间之后,接收到文件结束符的应用进程调用close关闭它的socket。这导致它的TCP也发送一个FIN N;
接收到这个FIN的源发送端TCP对它进行确认。
这样每个方向上都有一个FIN和ACK。
3.为什么建立连接要三次握手,断开连接要四次挥手
1.建立连接的时候,服务器在LISTEN的状态下,收到建立连接请求的SYN报文后,把ADK和SYN放在一个报文里发送给客户端。
2.而关闭连接时,服务器收到对方的FIN报文时,仅仅表示对方不再发送数据了,但是还能接收数据。
服务器立即发送确认信号是为了防止客户端重传FIN报文。
3.而服务器也未必所有数据都发给对方了,所以服务器可以立即关闭,也可以发送一写数据给对方后,再发送FIN报文给对方来表示同意现在的关闭连接。
4.因此,ACK和FIN一般都分开发送,从而导致多发了一次。
4.TIME-WAIT状态持续时间及原因
TCP在断开连接时,最先断开连接的一方最后会有一段时间处于TIME-WAIT状态,然后才会处于CLOSED状态。这个时间为2MSL,其中MSL为报文在传输线路中最大存活时间,一般设置为30秒到2分钟。也就是说TCP会处在TIME-WAIT状态持续1-4分钟。
为什么设置TIME-WAIT状态?原因有两个:
A) 因为最后发送的ACK报文可能丢失,导致对方再发送一次FIN报文,如果这时不处于TIME-WAIT状态,会用RST报文应答,这样会导致对方进入错误处理,而不是有序断开。当然这再次发送的ACK报文也可能丢失,也有可能导致对方再次发送的FIN报文。
B)是为了防止出现已经“失效的连接