首页 > 其他分享 >TCP三次握手和四次挥手

TCP三次握手和四次挥手

时间:2024-08-14 17:27:23浏览次数:7  
标签:socket 报文 TCP 连接 四次 服务器 握手 客户端

TCP三次握手和四次挥手详解

在网络通信中,TCP(传输控制协议)是一个非常重要的协议,用于确保数据在不可靠的网络环境中能够可靠传输。TCP通过三次握手(Three-way Handshake)建立连接,通过四次挥手(Four-way Termination)终止连接。


一、TCP三次握手

TCP的三次握手用于确保客户端和服务器之间的连接是可靠的,并且双方都准备好进行数据传输。三次握手的过程如下:

  1. 第一次握手:客户端发送SYN

    • 客户端向服务器发送一个SYN(同步序列编号)报文,表示客户端希望与服务器建立连接。此时,客户端进入SYN-SENT状态。
    • 报文中包含一个初始序列号(ISN),用于后续数据传输中的序列控制。
  2. 第二次握手:服务器发送SYN-ACK

    • 服务器接收到SYN报文后,向客户端发送一个SYN-ACK(同步确认)报文,表示同意建立连接。此时,服务器进入SYN-RECEIVED状态。
    • SYN-ACK报文包含服务器自己的ISN和客户端的ISN+1,表明服务器已收到客户端的SYN,并将自己的SYN发送给客户端。
  3. 第三次握手:客户端发送ACK

    • 客户端接收到SYN-ACK报文后,向服务器发送一个ACK(确认)报文,确认服务器的SYN已经收到。此时,客户端进入ESTABLISHED状态,连接建立成功。
    • 服务器接收到ACK报文后,也进入ESTABLISHED状态,表示连接已准备好进行数据传输。

通过三次握手,双方确认了彼此的发送和接收能力,连接正式建立。

 

这个过程类似于打电话的三个过程:

1.拨号。拨号相当于第一次握手。

2.接通。对方接通后为第二次握手。

3.回应。我方听到声音并回应为第三次握手。


二、TCP四次挥手

TCP的四次挥手用于终止客户端和服务器之间的连接,确保双方都能够优雅地关闭连接。四次挥手的过程如下:

  1. 第一次挥手:客户端发送FIN

    • 客户端发送一个FIN(终止)报文,表示客户端已经没有数据要发送了,要求关闭连接。此时,客户端进入FIN-WAIT-1状态。
    • FIN报文可能包含最后一段数据,或者仅仅表示终止发送。
  2. 第二次挥手:服务器发送ACK

    • 服务器接收到FIN报文后,向客户端发送一个ACK报文,确认客户端的FIN已经收到。此时,服务器进入CLOSE-WAIT状态,客户端进入FIN-WAIT-2状态。
    • 此时,服务器可能仍有未发送的数据,因此不会立即关闭连接。
  3. 第三次挥手:服务器发送FIN

    • 服务器发送完所有剩余的数据后,向客户端发送一个FIN报文,表示服务器也准备关闭连接。此时,服务器进入LAST-ACK状态。
    • 客户端接收到FIN报文后,发送最后一个ACK报文,确认收到服务器的FIN。此时,客户端进入TIME-WAIT状态。
  4. 第四次挥手:客户端发送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的三次握手和四次挥手过程。

输出:

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.

 

标签:socket,报文,TCP,连接,四次,服务器,握手,客户端
From: https://www.cnblogs.com/zx618/p/18359423

相关文章

  • TcpSocket在切后台后如何保活
    1)TcpSocket在切后台后如何保活2)MagicaClothes2插件与Burst编译问题3)粒子拖尾合批失败怎么办4)如何让射线追踪跟随我FPS游戏的十字准星进行移动这是第398篇UWA技术知识分享的推送,精选了UWA社区的热门话题,涵盖了UWA问答、社区帖子等技术知识点,助力大家更全面地掌握和学习。UWA社......
  • TCP协议
    TCP/IP协议有哪些应用场景?TCP/IP协议由于其可靠性和广泛的适用性,被应用于多种场景,以下是一些主要的应用场景:网页浏览:当你在浏览器中输入网址时,浏览器会通过HTTP(超文本传输协议,基于TCP)或HTTPS(安全的HTTP)与网站服务器通信,获取网页内容。电子邮件发送和接收:电子邮件客户端使......
  • 0228-TCP 的标记和选项
    环境Time2022-11-24WSL-Ubuntu22.04Rust1.65.0pnet0.31.0tun-tap0.1.3前言说明参考:https://docs.rs/pnet/latest/pnet/index.html参考:https://www.cnblogs.com/lshs/p/6038494.html目标了解TCP协议头中的flags和options字段的含义。main.rsusepnet::pa......
  • 0230-TCP 发送和接收
    环境Time2022-11-25WSL-Ubuntu22.04Rust1.65.0前言说明参考:https://doc.rust-lang.org/std/net/struct.TcpListener.html目标之前认识了TCP报文头,这里去除报文头的细节,直接通信。main.rsTCP由标准库直接支持,可以直接使用。连接上去后,服务器返回一个hello。us......
  • 0227-TCP 请求报文
    环境Time2022-11-24WSL-Ubuntu22.04Rust1.65.0pnet0.31.0tun-tap0.1.3前言说明参考:https://docs.rs/pnet/latest/pnet/index.htmlRFC793目标了解TCP协议头中的字段,其也是基于IP协议的。配置TUNIP地址不要和主机的网卡地址在一个段,以便选择这个网卡进行......
  • Modbus Tcp数据通讯实测
    ModbusTCP数据帧ModbusTCP的数据帧可分为两部分:MBAP+PDU。报文头MBAPMBAP为报文头,长度为7字节,组成如下:  帧结构PDUPDU由功能码+数据组成。功能码为1字节,数据长度不定,由具体功能决定。功能码Modbus的操作对象有四种:线圈、离散输入、保持寄存器、输入寄存器。 ......
  • WebSockets:原理、握手及代码实现
    1.WebSockets原理WebSockets是HTML5标准的一部分,旨在为Web应用提供全双工通信能力。与传统的HTTP请求不同,WebSockets连接一旦建立,就可以在客户端和服务器之间自由传输数据,而不再需要每次通信都重新建立连接。工作流程:建立连接:客户端通过HTTP协议发起WebSocket握......
  • springboot集成integration-ip搭建TCP Client
    1、创建客户端属性类tcp:client:host:127.0.0.1port:5001@Data@ConfigurationProperties("tcp.client")publicclassTcpClientProperties{privateStringhost;privateIntegerport;}2、集成integration-ip配置@Slf4j@Configuration@......
  • 带你全新理解TCP/IP协议
       协议规定了双方互相沟通时遵守的规则:一方是否主动握手,鞠躬多深,谁先从门口走过,在路的哪一侧行驶,等等。虽然有些协议是法律强制规定的,比如在路的哪一边行驶,但生活中的大多数协议都不太正式。与之形成鲜明对比的是,网络协议是非常精确地进行规范的。   互联网有很多......
  • 三报文握手经典例题详解
    如图,有如下TCP连接。主机V通过三次握手与主机U建立一个TCP连接1.有三个TCP段(标号为A、B、C) 被传送,请在下面括号中填入各段的SYN标志位、序号(seq)、确认号(ack)段A:  SYN=(  1 ),seq=500段B:  SYN=(  1 ),seq=600,ack=(  501    )段C:  ......