建立tcp连接需要三次握手,断开连接需要4次。
三次握手:首先Client端发送连接请求报文,Server段接受连接后回复ACK报文,并为这次连接分配资源。Client端接收到ACK报文后也向Server段发生ACK报文,并分配资源,这样TCP连接就建立了。
为什么需要三次握手?
谢希仁版《计算机网络》中的例子是这样的,“已失效的连接请求报文段”的产生在这样一种情况下:client发出的第一个连接请求报文段并没有丢失,而是在某个网络结点长时间的滞留了,以致延误到连接释放以后的某个时间才到达server。本来这是一个早已失效的报文段。但server收到此失效的连接请求报文段后,就误认为是client再次发出的一个新的连接请求。于是就向client发出确认报文段,同意建立连接。假设不采用“三次握手”,那么只要server发出确认,新的连接就建立了。由于现在client并没有发出建立连接的请求,因此不会理睬server的确认,也不会向server发送ack包。server却以为新的运输连接已经建立,并一直等待client发来数据。这样,server的很多资源就白白浪费掉了。采用“三次握手”的办法可以防止上述现象发生。例如刚才那种情况,client不会向server的确认发出确认。server由于收不到确认,就知道client并没有要求建立连接。在谢希仁著《计算机网络》第四版中讲“三次握手”的目的是“为了防止已失效的连接请求报文段突然又传送到了服务端,因而产生错误”。在另一部经典的《计算机网络》一书中讲“三次握手”的目的是为了解决“网络中存在延迟的重复分组”的问题。这两种不同的表述其实阐明的是同一个问题。
那如何断开连接呢?简单的过程如下
1.假设客户端主动断开连接,向服务器发送fin报文,这个报文主要告诉服务器客户端已经没有数据想要传给服务器,但是服务器你如果有数据没传输完的话,先不用断开socket连接,可以继续发你的数据,先给客户端发ack报文。2.服务器收到报文,看了fin的报文,给客户端发了ack报文,告诉客户端服务器已经收到了消息,但我还有事没做完,让客户端等会。3.这时候客户端进入FIN_WAIT状态,即等待服务器给他发fin报文。当服务器确定传输的数据都发完了,再向客户端发送fin报文。告诉客户端我已经传输完所有数据了,可以关闭socket连接。4.客户端收到fin报文,就知道socket要断开连接了,向服务器发送ack报文,但客户端不确定这个报文是否传到服务器了,于是进入Time_wait状态,如果服务器没有收到ack报文则进行重传,如果等待30s没有收到消息说明连接服务器端已经关闭了,客户端可以安心关闭了。这样tcp就断开了。
【注意】在TIME_WAIT状态中,如果TCP client端最后一次发送的ACK丢失了,它将重新发送。TIME_WAIT状态中所需要的时间是依赖于实现方法的。典型的值为30秒、1分钟和2分钟。等待之后连接正式关闭,并且所有的资源(包括端口号)都被释放。
为什么连接的时候是三次握手,关闭的时候却是四次握手?
答:因为当Server端收到Client端的SYN连接请求报文后,可以直接发送SYN+ACK报文。其中ACK报文是用来应答的,SYN报文是用来同步的。但是关闭连接时,当Server端收到FIN报文时,很可能并不会立即关闭SOCKET,所以只能先回复一个ACK报文,告诉Client端,"你发的FIN报文我收到了"。只有等到我Server端所有的报文都发送完了,我才能发送FIN报文,因此不能一起发送。故需要四步握手。
网友评论