TCP协议端口状态说明:CLOSE-WAIT、TIME-WAIT 、LISTENING、SYN_SENT、ESTABLISHED、LAST-ACK

本文详细解析TCP协议的各种连接状态,包括LISTENING、SYN_SENT、ESTABLISHED等,阐述了每种状态的含义及状态之间的转换过程,有助于理解网络连接的工作原理。

了解TCP协议端口的连接状态,对排除和定位网络或系统故障会有很大帮助,因此了解一下是有必要的:

一、LISTENING
提供某种服务,侦听远方 TCP 端口的连接请求,当提供的服务没有被连接时,处于LISTENING 状态,端口是开放的,等待被连接。

二、SYN_SENT (客户端状态)
客户端调用 connect,发送一个 SYN 请求建立一个连接,在发送连接请求后等待匹配的连接请求,此时状态为 SYN_SENT.

三、SYN_RECEIVED (服务端状态)
在收到和发送一个连接请求后,等待对方对连接请求的确认,当服务器收到客户端发送的同步信号时,将标志位 ACK 和 SYN 置1发送给客户端,此时服务器端处于SYN_RECEIVED 状态,如果连接成功了就变为 ESTABLISHED,正常情况下 SYN_RECEIVED 状态非常短暂。

四、ESTABLISHED
ESTABLISHED 状态是表示两台机器正在传输数据。

五、FIN-WAIT-1
等待远程 TCP 连接中断请求,或先前的连接中断请求的确认,主动关闭端应用程序调用close,TCP 发出 FIN 请求主动关闭连接,之后进入 FIN_WAIT1 状态。

六、FIN-WAIT-2
从远程 TCP 等待连接中断请求,主动关闭端接到 ACK 后,就进入了 FIN-WAIT-2 .这是在关闭连接时,客户端和服务器两次握手之后的状态,是著名的半关闭的状态了,在这个状态下,应用程序还有接受数据的能力,但是已经无法发送数据,但是也有一种可能是,客户端一直处于 FIN_WAIT_2 状态,而服务器则一直处于 CLOSE_WAIT 状态,而直到应用层来决定关闭这个状态。

附半关闭例图:
在这里插入图片描述
七、CLOSE-WAIT
等待从本地用户发来的连接中断请求 ,被动关闭端 TCP 接到FIN后,就发出 ACK 以回应 FIN 请求(它的接收也作为文件结束符传递给上层应用程序),并进入CLOSE_WAIT.

八、CLOSING
等待远程 TCP 对连接中断的确认,处于此种状态比较少见。

九、LAST-ACK
等待原来的发向远程 TCP 的连接中断请求的确认,被动关闭端一段时间后,接收到文件结束符的应用程序将调用 CLOSE 关闭连接, TCP 也发送一个 FIN,等待对方的 ACK.进入LAST-ACK。

十、TIME-WAIT
在主动关闭端接收到 FIN 后,TCP 就发送 ACK 包,并进入TIME-WAIT 状态,等待足够的时间以确保远程 TCP 接收到连接中断请求的确认,很大程度上保证了双方都可以正常结束,但是也存在问题,须等待 2MSL 时间的过去才能进行下一次连接。

十一、CLOSED
被动关闭端在接受到 ACK 包后,就进入了 closed 的状态,连接结束,没有任何连接状态。

附TCP正常连接建立和终止所对应的状态图
在这里插入图片描述
状态迁移过程:
a、客户端:
CLOSED->SYN_SENT->ESTABLISHED->FIN_WAIT_1->FIN_WAIT_2->TIME_WAIT->CLOSED

b、服务端
CLOSED->LISTEN->SYN_RECEIVED->ESTABLISHED->CLOSE_WAIT->LAST_ACK->CLOSE

在众多状态中,经常关注的有两个:TIME_WAIT、CLOSE_WAIT。

附状态迁移过程图:
在这里插入图片描述

转自:
《jessezeng TCP协议端口状态说明:CLOSE-WAIT、TIME-WAIT 、LISTENING、SYN_SENT、ESTABLISHED、LAST-ACK》

TCP协议状态转换过程是网络通信中非常关键的一部分,尤其是在建立和终止连接时的状态迁移。TCP定义了11种状态来管理连接的生命周期,包括连接的建立、数据传输以及连接的终止。 ### TCP 协议的 11 种状态 TCP 协议中定义的 11 种状态包括: 1. **LISTEN** - 服务器正在等待来自客户端的连接请求。 2. **SYN_SENT** - 客户端已经发送了 SYN 报文段,并等待服务器的 SYN-ACK 响应。 3. **SYN_RCVD** - 服务器已经接收到客户端的 SYN 报文段,并发送了自己的 SYN 报文段和 ACK 报文段。 4. **ESTABLISHED** - 连接已经建立,数据可以在两个方向上传输。 5. **FIN_WAIT_1** - 应用程序已经请求关闭连接,TCP 已经发送了 FIN 报文段,并等待对方的 FIN-ACK 响应。 6. **FIN_WAIT_2** - TCP 已经接收到对方的 ACK 报文段,现在等待对方发送 FIN 报文段。 7. **CLOSE_WAIT** - 对方已经发送了 FIN 报文段,本方需要关闭连接,应用程序应该关闭连接并发送自己的 FIN 报文段。 8. **CLOSING** - 双方几乎同时关闭连接,TCP 已经发送了 FIN 报文段,并且也接收到对方的 FIN 报文段,但还没有确认。 9. **LAST_ACK** - 本地已经发送了 FIN 报文段,并且接收到对方的 FIN 报文段,现在等待对方的 ACK 报文段。 10. **TIME_WAIT** - 连接已经关闭,但是为了确保最后的 ACK 报文段能够到达对方,TCP 会保持在这个状态一段时间(通常是 2 倍的最大段生存时间,即 2MSL)。 11. **CLOSED** - 连接已经完全关闭,没有数据传输正在进行。 ### 状态转换图 下面是一个简化的TCP状态转换图描述: ``` +---------+ +---------+ +---------+ | LISTEN |---->|SYN_RCVD |---->|ESTABLISH| +---------+ +---------+ +---------+ | | | | | | v v v +---------+ +---------+ +---------+ |SYN_SENT |<----|SYN_RCVD |<----|FIN_WAIT_1| +---------+ +---------+ +---------+ | | | | | | v v v +---------+ +---------+ +---------+ | CLOSED | |CLOSE_WAIT | |FIN_WAIT_2| +---------+ +---------+ +---------+ | | | | | | v v v +---------+ +---------+ +---------+ | | |LAST_ACK | |TIME_WAIT| +---------+ +---------+ +---------+ ``` 请注意,这个图是一个简化版本,实际的状态转换图更为复杂。在实际应用中,TCP状态转换图会包含所有11种状态之间的转换,并且每一种状态转换都对应着特定的事件和动作。 ### 状态转换路径 - **客户端路径**:客户端从发送SYN开始,经历SYN_SENT状态,直到收到SYN-ACK后进入ESTABLISHED状态。当客户端完成数据传输后,它会发送一个FIN报文段,进入FIN_WAIT_1状态,然后接收到ACK后进入FIN_WAIT_2状态,最后接收到对方的FIN报文段后进入TIME_WAIT状态- **服务器端路径**:服务器从LISTEN状态开始,当接收到SYN报文段后进入SYN_RCVD状态,发送SYN-ACK后进入SYN_RCVD状态,然后接收到客户端的ACK后进入ESTABLISHED状态。当服务器完成数据传输后,它会发送一个FIN报文段,进入CLOSE_WAIT状态,然后接收到客户端的FIN报文段后进入LAST_ACK状态,最后接收到ACK后进入CLOSED状态。 ### 示例代码 以下是一个简单的Python代码示例,用于演示如何使用socket编程来观察TCP连接的状态变化: ```python import socket def start_server(): server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) server_socket.bind(('localhost', 9999)) server_socket.listen(1) print("Server is listening on port 9999...") conn, addr = server_socket.accept() print(f"Connection from {addr}") # 接收数据 data = conn.recv(1024) print(f"Received: {data.decode()}") # 发送数据 conn.sendall(b"Hello, client!") # 关闭连接 conn.close() server_socket.close() if __name__ == "__main__": start_server() ``` ```python import socket def start_client(): client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) client_socket.connect(('localhost', 9999)) # 发送数据 client_socket.sendall(b"Hello, server!") # 接收数据 data = client_socket.recv(1024) print(f"Received: {data.decode()}") # 关闭连接 client_socket.close() if __name__ == "__main__": start_client() ``` 这段代码展示了客户端和服务器的基本交互过程,从建立连接到数据传输再到关闭连接,可以观察到TCP连接的不同状态变化[^1]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值