首页 > 极客资料 博客日记
TCP三次握手和四次挥手
2024-08-14 17:30:03极客资料围观24次
这篇文章介绍了TCP三次握手和四次挥手,分享给大家做个参考,收藏极客之家收获更多编程知识
TCP三次握手和四次挥手详解
在网络通信中,TCP(传输控制协议)是一个非常重要的协议,用于确保数据在不可靠的网络环境中能够可靠传输。TCP通过三次握手(Three-way Handshake)建立连接,通过四次挥手(Four-way Termination)终止连接。
一、TCP三次握手
TCP的三次握手用于确保客户端和服务器之间的连接是可靠的,并且双方都准备好进行数据传输。三次握手的过程如下:
-
第一次握手:客户端发送SYN
- 客户端向服务器发送一个SYN(同步序列编号)报文,表示客户端希望与服务器建立连接。此时,客户端进入SYN-SENT状态。
- 报文中包含一个初始序列号(ISN),用于后续数据传输中的序列控制。
-
第二次握手:服务器发送SYN-ACK
- 服务器接收到SYN报文后,向客户端发送一个SYN-ACK(同步确认)报文,表示同意建立连接。此时,服务器进入SYN-RECEIVED状态。
- SYN-ACK报文包含服务器自己的ISN和客户端的ISN+1,表明服务器已收到客户端的SYN,并将自己的SYN发送给客户端。
-
第三次握手:客户端发送ACK
- 客户端接收到SYN-ACK报文后,向服务器发送一个ACK(确认)报文,确认服务器的SYN已经收到。此时,客户端进入ESTABLISHED状态,连接建立成功。
- 服务器接收到ACK报文后,也进入ESTABLISHED状态,表示连接已准备好进行数据传输。
通过三次握手,双方确认了彼此的发送和接收能力,连接正式建立。
这个过程类似于打电话的三个过程:
1.拨号。拨号相当于第一次握手。
2.接通。对方接通后为第二次握手。
3.回应。我方听到声音并回应为第三次握手。
二、TCP四次挥手
TCP的四次挥手用于终止客户端和服务器之间的连接,确保双方都能够优雅地关闭连接。四次挥手的过程如下:
-
第一次挥手:客户端发送FIN
- 客户端发送一个FIN(终止)报文,表示客户端已经没有数据要发送了,要求关闭连接。此时,客户端进入FIN-WAIT-1状态。
- FIN报文可能包含最后一段数据,或者仅仅表示终止发送。
-
第二次挥手:服务器发送ACK
- 服务器接收到FIN报文后,向客户端发送一个ACK报文,确认客户端的FIN已经收到。此时,服务器进入CLOSE-WAIT状态,客户端进入FIN-WAIT-2状态。
- 此时,服务器可能仍有未发送的数据,因此不会立即关闭连接。
-
第三次挥手:服务器发送FIN
- 服务器发送完所有剩余的数据后,向客户端发送一个FIN报文,表示服务器也准备关闭连接。此时,服务器进入LAST-ACK状态。
- 客户端接收到FIN报文后,发送最后一个ACK报文,确认收到服务器的FIN。此时,客户端进入TIME-WAIT状态。
-
第四次挥手:客户端发送ACK
- 客户端发送的最后一个ACK报文确认了服务器的FIN报文后,客户端进入TIME-WAIT状态,等待一段时间(通常为2倍的最大报文段寿命),确保服务器收到ACK。
- 如果在TIME-WAIT状态期间没有收到任何重传的FIN报文,客户端将进入CLOSED状态,表示连接已经完全关闭。
通过四次挥手,TCP连接得以优雅地关闭,确保所有的数据都得到了完整的传输和确认。
示例:
import socket import time # 服务端代码 def server(): # 创建TCP套接字 server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 绑定IP地址和端口号 server_socket.bind(('localhost', 12345)) # 监听连接请求 server_socket.listen(1) print("Server is listening...") # 接受客户端连接 conn, addr = server_socket.accept() print(f"Connected by {addr}") # 模拟服务器发送数据 conn.sendall(b'Hello, Client!') # 接收客户端消息 data = conn.recv(1024) print(f"Received: {data.decode()}") # 关闭连接 conn.close() server_socket.close() print("Server connection closed.") # 客户端代码 def client(): # 创建TCP套接字 client_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) # 连接服务器 client_socket.connect(('localhost', 12345)) print("Client connected to server.") # 接收服务器消息 data = client_socket.recv(1024) print(f"Received: {data.decode()}") # 模拟客户端发送数据 client_socket.sendall(b'Thank you, Server!') # 关闭连接 client_socket.close() print("Client connection closed.") # 模拟TCP三次握手和四次挥手 if __name__ == "__main__": # 启动服务端 import threading server_thread = threading.Thread(target=server) server_thread.start() # 延迟启动客户端以确保服务端已启动 time.sleep(1) # 启动客户端 client() # 等待服务端线程结束 server_thread.join()
-
服务端部分:
- 使用
socket.socket()
创建一个TCP套接字,并绑定到localhost
上的端口12345
。 - 通过
listen()
方法让服务器开始监听客户端连接。 - 使用
accept()
接受客户端的连接请求,并返回一个新的套接字conn
,用于与客户端进行通信。 - 服务器发送一条消息给客户端,并接收客户端的响应后,关闭连接。
- 使用
-
客户端部分:
- 同样使用
socket.socket()
创建一个TCP套接字。 - 通过
connect()
方法连接到服务器的IP和端口。 - 客户端接收到服务器的消息后,发送一个响应消息,并关闭连接。
- 同样使用
-
主程序部分:
- 使用Python的
threading
模块来同时运行服务器和客户端,模拟TCP的三次握手和四次挥手过程。
- 使用Python的
输出:
Server is listening... Client connected to server. Connected by ('127.0.0.1', random_port) Received: Hello, Client! Received: Thank you, Server! Client connection closed. Server connection closed.
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:jacktools123@163.com进行投诉反馈,一经查实,立即删除!
标签:
相关文章
最新发布
- Nuxt.js 应用中的 prerender:routes 事件钩子详解
- 【问题解决】Tomcat由低于8版本升级到高版本使用Tomcat自带连接池报错无法找到表空间的问题
- 【FAQ】HarmonyOS SDK 闭源开放能力 —Vision Kit
- 六、Spring Boot集成Spring Security之前后分离认证流程最佳方案
- 《JVM第7课》堆区
- .NET 8 高性能跨平台图像处理库 ImageSharp
- 还在为慢速数据传输苦恼?Linux 零拷贝技术来帮你!
- 刚毕业,去做边缘业务,还有救吗?
- 如何避免 HttpClient 丢失请求头:通过 HttpRequestMessage 解决并优化
- 让性能提升56%的Vue3.5响应式重构之“版本计数”