您的位置:首页 > 理论基础 > 计算机网络

计算机网络笔记--TCP三次握手与四次挥手过程状态分析

2016-08-19 15:07 1251 查看
三次握手:

由于TCP协议提供可靠的连接服务,于是采用有保障的三次握手方式来创建一个TCP连接。三次握手的具体过程如下:

1.客户端发送一个带SYN标志的TCP报文(报文1)到服务器端,表示希望建立一个TCP连接。

2.服务器发送一个带ACK标志和SYN标志的TCP报文(报文2)给客户端,ACK用于对报文1的回应,SYN用于询问客户端是否准备好进行数据传输。

3.客户端发送一个带ACK标志的TCP报文(报文3),作为报文2的回应。

四次挥手:

由于TCP连接是全双工的,因此每个方向都必须单独进行关闭。原则是主动关闭的一方(如已传输完所有数据等原因)发送一个FIN报文来表示终止这个方向的连接,收到一个FIN意味着这个方向不再有数据流动,但另一个方向仍能继续发送数据,直到另一个方向也发送FIN报文。四次挥手的具体过程如下:

1.客户端发送一个FIN报文给服务器,表示我将关闭客户端到服务器端这个方向的连接。

2.服务器收到此报文后,发送一个ACK报文给客户端。

3.服务器发送一个FIN报文给客户端,表示自己也将关闭服务器端到客户端这个方向的连接。

4.客户端收到此报文后,发回一个ACK报文给服务器。

三次握手与四次挥手过程状态如下图所示:



【TCP相关疑问】

最后整理几个常见的TCP相关的疑问:

Q1. 为什么在TCP协议里,建立连接是三次握手,而关闭连接却是四次握手呢?

A1. 因为当处于LISTEN 状态的服务器端SOCKET当收到SYN报文(客户端希望新建一个TCP连接)后,它可以把ACK(应答作用)和SYN(同步作用)放在同一个报文里来发送给客户端。但在关闭TCP连接时,当收到对方的FIN报文时,对方仅仅表示对方没有数据发送给你了,但未必你的所有数据都已经全部发送给了对方,所以你大可不必马上关闭SOCKET(发送一个FIN报文),等你发送完剩余的数据给对方之后,再发送FIN报文给对方来表示你同意现在关闭连接了,所以通常情况下,这里的ACK报文和FIN报文都是分开发送的。

Q2. 为什么TIME_WAIT 状态还需要等2*MSL秒之后才能返回到CLOSED 状态呢?

A2. 因为虽然双方都同意关闭连接了,而且握手的4个报文也都发送完毕,按理可以直接回到CLOSED 状态(就好比从SYN_SENT 状态到ESTABLISH 状态那样),但是我们必须假想网络是不可靠的,你无法保证你最后发送的ACK报文一定会被对方收到,就是说对方处于LAST_ACK 状态下的SOCKET可能会因为超时未收到ACK报文,而重发FIN报文,所以这个TIME_WAIT 状态的作用就是用来重发可能丢失的ACK报文。

Q3. 关闭TCP连接一定需要4次挥手吗?

A3. 不一定,4次挥手关闭TCP连接是最安全的做法。但在有些时候,我们不喜欢TIME_WAIT 状态(如当MSL数值设置过大导致服务器端有太多TIME_WAIT状态的TCP连接,减少这些条目数可以更快地关闭连接,为新连接释放更多资源),这时我们可以通过设置SOCKET变量的SO_LINGER标志来避免SOCKET在close()之后进入TIME_WAIT状态,这时将通过发送RST强制终止TCP连接(取代正常的TCP四次握手的终止方式)。但这并不是一个很好的主意,TIME_WAIT 对于我们来说往往是有利的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: