TCP 四次挥手的过程

举报
赵KK日常技术记录 发表于 2023/07/14 10:52:19 2023/07/14
【摘要】 TCP 四次挥手的过程在 TCP 通信的结束时,客户端与服务器端都需要向对方发送一个 FIN 报文段以终止连接。四次挥手的具体过程如下:客户端主动关闭连接,发送一个 FIN 报文段服务器收到客户端发送的 FIN 报文段后,向客户端回复一个 ACK 报文段,表示已经收到了客户端的终止请求服务器关闭连接,向客户端发送一个 FIN 报文段客户端收到服务器发送的 FIN 报文段后,向服务器回复一个 ...

TCP 四次挥手的过程

在 TCP 通信的结束时,客户端与服务器端都需要向对方发送一个 FIN 报文段以终止连接。四次挥手的具体过程如下:

  1. 客户端主动关闭连接,发送一个 FIN 报文段
  2. 服务器收到客户端发送的 FIN 报文段后,向客户端回复一个 ACK 报文段,表示已经收到了客户端的终止请求
  3. 服务器关闭连接,向客户端发送一个 FIN 报文段
  4. 客户端收到服务器发送的 FIN 报文段后,向服务器回复一个 ACK 报文段,表示已经收到了服务器的终止请求。

此时,TCP 连接已经彻底关闭,双方不再进行数据传输。

TIME_WAIT 的作用及为什么设置两倍 MSL 时间

在 TCP 四次挥手过程中,一方发送完最后的 ACK 报文段后并不会立刻关闭连接,而是要等待一个 TIME_WAIT 的状态,这个状态的作用有以下几点:

  1. 确保对方已经收到了自己的 ACK 报文段,如果没有收到可以重传,避免出现连接中断但还存在未确认的数据包等问题。
  2. 等待一段时间,确保对方没有发送其他的数据包,防止出现错误的重复连接等问题。
  3. 等待一段时间,确保旧的连接状态已经被清除,不会对新连接产生影响。

MSL 时间是 TCP 协议中的一个参数,表示最大报文存活时间。设置 TIME_WAIT 的时间至少为两倍 MSL 的原因如下:

  1. 确保在网络中传输的所有报文都已经消失,防止旧数据包干扰新的连接。
  2. 在一些网络环境下,可能会出现一些延迟或重传等问题,如果只设置 MSL 时间,可能会出现连接还没有完全关闭就被错误地重用的问题。

因此,通过将 TIME_WAIT 设置为两倍 MSL,可以确保连接被彻底关闭并且不会对新连接造成任何影响。

以下是 Java 实现 TCP 四次挥手过程的示例代码:

import java.io.*;
import java.net.*;

public class TCPClient {
    public static void main(String[] args) throws Exception {
        String host = "localhost";
        int port = 9999;

        Socket clientSocket = new Socket(host, port);

        PrintWriter out = new PrintWriter(
                clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream()));
        BufferedReader stdIn = new BufferedReader(
                new InputStreamReader(System.in));

        String userInput;
        while ((userInput = stdIn.readLine()) != null) {
            out.println(userInput);

            if (userInput.equals("bye")) {
                break;
            }

            System.out.println("Server: " + in.readLine());
        }

        in.close();
        out.close();
        stdIn.close();
        clientSocket.close();
    }
}

import java.io.*;
import java.net.*;

public class TCPServer {
    public static void main(String[] args) throws Exception {
        int port = 9999;

        ServerSocket serverSocket = new ServerSocket(port);
        Socket clientSocket = serverSocket.accept();

        PrintWriter out = new PrintWriter(
                clientSocket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
                new InputStreamReader(clientSocket.getInputStream()));

        String inputLine;
        while ((inputLine = in.readLine()) != null) {
            if (inputLine.equals("bye")) {
                break;
            }

            System.out.println("Client: " + inputLine);
            out.println(inputLine.toUpperCase());
        }

        out.close();
        in.close();
        clientSocket.close();
        serverSocket.close();
    }
}

在示例中,客户端向服务器发送消息,并且在收到服务器回复后继续发送,直到发送 bye 指令结束连接。服务器接收到消息后将其转换为大写并返回给客户端,直到收到 bye 指令结束连接。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。