计算机网络学习--------三次握手与四次挥手

发布于:2025-08-01 ⋅ 阅读:(18) ⋅ 点赞:(0)

        计算机网络:TCP 的三次握手与四次挥手(基于 Java)​在计算机网络的世界里,TCP(传输控制协议)犹如一位严谨的通信管家,确保数据在网络中可靠传输。而三次握手和四次挥手作为 TCP 建立和终止连接的关键环节,是实现可靠通信的核心所在。

        三次握手是 TCP 协议中建立连接的过程。简单来说,就是客户端和服务器通过三次数据包的交互,来确认双方的发送和接收能力都处于正常状态,最终建立起一条可靠的通信链路。它就像两个人打电话,先问 “你能听到我说话吗”,对方回应 “能听到,你能听到我吗”,再回应 “能听到”,这样通话连接就建立好了。​

        四次挥手则是 TCP 协议中终止连接的过程。由于 TCP 连接是全双工的,双方可以同时发送数据,所以关闭连接时需要双方分别确认,通过四次数据包交互,逐步关闭各自的发送通道,最终释放连接所占用的资源。这好比通话结束时,一方说 “我说完了”,对方回应 “知道了”,然后对方说 “我也说完了”,最后一方回应 “好的,再见”,通话连接就此终止。​

        三次握手的作用​有:

(1)确认通信能力:通过三次交互,双方都能确认对方既能发送数据,也能接收数据,避免了因一方通信能力故障而导致的数据传输失败。​

(2)同步序列号:TCP 通过序列号来保证数据的有序性和完整性,三次握手过程中,双方会交换初始序列号,为后续数据传输时的排序和去重打下基础。​

(3)防止无效连接:可以避免网络中滞留的过期连接请求报文被服务器误接收,从而防止服务器因建立无效连接而浪费资源。​

        而四次挥手的主要作用有:​

(1)优雅释放资源:确保双方已传输的数据都被正确接收,不会在连接关闭时出现数据丢失的情况。​

(2)处理半关闭状态:支持一方先关闭发送通道,但仍能继续接收数据的 “半关闭” 场景,以适应实际通信中可能出现的不对称关闭需求。​

(3)避免连接残留:通过双方的确认,彻底释放连接所占用的端口、缓存等资源,防止资源泄漏。​

        三次握手的主要原理为:

(1)第一次握手:客户端向服务器发送一个 SYN 报文段,其中包含客户端的初始序列号,并将 SYN 标志位设为 1。此时客户端进入 SYN_SENT 状态,等待服务器的响应。​

(2)第二次握手:服务器收到 SYN 报文后,会返回一个 SYN+ACK 报文段。其中 SYN 标志位设为 1,包含服务器的初始序列号;ACK 标志位设为 1,确认号为客户端初始序列号 + 1,表示已收到客户端的 SYN 报文。此时服务器进入 SYN_RCVD 状态。​

(3)第三次握手:客户端收到 SYN+ACK 报文后,发送一个 ACK 报文段,ACK 标志位设为 1,确认号为服务器初始序列号 + 1,表示已收到服务器的 SYN 报文。客户端发送完毕后进入 ESTABLISHED 状态,服务器收到 ACK 后也进入 ESTABLISHED 状态,双方开始传输数据。​

        而四次挥手的原理为:​

(1)第一次挥手:假设客户端主动关闭连接,发送一个 FIN 报文段,FIN 标志位设为 1,序列号为客户端已发送数据的最后一个字节序号 + 1。客户端进入 FIN_WAIT_1 状态,表明不再发送数据,但仍可接收数据。​

(2)第二次挥手:服务器收到 FIN 报文后,返回一个 ACK 报文段,确认号为客户端 FIN 的序列号 + 1,表明已收到关闭请求。服务器进入 CLOSE_WAIT 状态,客户端收到 ACK 后进入 FIN_WAIT_2 状态,等待服务器的关闭通知。​

(3)第三次挥手:服务器完成剩余数据传输后,向客户端发送 FIN 报文段,FIN 标志位设为 1,序列号为服务器已发送数据的最后一个字节序号 + 1。服务器进入 LAST_ACK 状态,等待客户端确认。​

(4)第四次挥手:客户端收到 FIN 报文后,返回 ACK 报文段,确认号为服务器 FIN 的序列号 + 1,并进入 TIME_WAIT 状态。服务器收到 ACK 后进入 CLOSED 状态;客户端等待一段时间(通常为 2MSL)后,也进入 CLOSED 状态,连接彻底释放。​

        三次握手的应用场景​主要为:

(1)HTTP/HTTPS 通信:当我们在浏览器中输入网址访问网页时,浏览器与 Web 服务器之间首先要通过三次握手建立 TCP 连接,然后才能传输网页数据。​

(2)文件传输:像 FTP 协议进行文件传输时,依赖 TCP 连接,三次握手保证了大文件在传输过程中不会因连接问题而丢失数据。​

(3)邮件发送:邮件客户端与邮件服务器之间发送邮件时,也需要通过三次握手建立 TCP 连接,确保邮件内容能完整送达。​

        而四次挥手的应用场景​主要为;

(1)网页浏览结束:当我们关闭浏览器或者从一个网页跳转到另一个网页时,客户端与原 Web 服务器会通过四次挥手释放 TCP 连接。​

(2)文件传输完成:FTP 文件传输完成后,双方会进行四次挥手关闭连接,释放所占用的资源。​

(3)网络异常中断处理:当网络出现故障或者连接超时等异常情况时,通信双方会通过四次挥手来优雅地关闭连接。​

        三次握手的优缺点​分别是:

        优点:仅通过三次交互就可以确认双方的通信能力,在可靠性和效率之间取得了较好的平衡;同步序列号机制为数据的有序传输提供了保障;能有效防止过期连接请求导致的资源浪费。​

        缺点:相比 UDP 等无连接协议,建立连接的耗时更长,不适合对实时性要求极高的场景,如实时视频通话;可能会遭受 SYN 洪水攻击,攻击者发送大量伪造的 SYN 报文,导致服务器资源耗尽。​

        而四次挥手的优缺点​主要有;

        优点:支持半关闭状态,能适应复杂的通信场景;通过 TIME_WAIT 状态确保最后一个 ACK 被收到,避免连接残留;能彻底释放资源,防止端口被长期占用。​

        缺点:四次交互增加了连接关闭的耗时,在高并发场景下可能会影响系统的吞吐量;TIME_WAIT 状态默认等待时间较长,若短时间内大量连接关闭,可能会导致端口耗尽。​

        在 Java 中,我们可以使用 Socket 和 ServerSocket 来模拟 TCP 的连接建立和关闭过程,其中就隐含了三次握手和四次挥手的操作(由操作系统底层实现)。

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;

// 服务端
public class TCPServer {
    public static void main(String[] args) {
        ServerSocket serverSocket = null;
        Socket clientSocket = null;
        InputStream in = null;
        OutputStream out = null;
        try {
            // 创建ServerSocket,监听指定端口
            serverSocket = new ServerSocket(8888);
            System.out.println("服务器启动,等待客户端连接...");
            
            // 等待客户端连接,accept()方法会阻塞,直到有客户端连接
            // 这里隐含了三次握手的过程
            clientSocket = serverSocket.accept();
            System.out.println("客户端连接成功,客户端地址:" + clientSocket.getInetAddress());
            
            // 获取输入流和输出流
            in = clientSocket.getInputStream();
            out = clientSocket.getOutputStream();
            
            // 读取客户端发送的数据
            byte[] buffer = new byte[1024];
            int len = in.read(buffer);
            System.out.println("收到客户端数据:" + new String(buffer, 0, len));
            
            // 向客户端发送数据
            String response = "Hello, Client!";
            out.write(response.getBytes());
            out.flush();
            
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 关闭资源,隐含了四次挥手的过程
                if (in != null) in.close();
                if (out != null) out.close();
                if (clientSocket != null) clientSocket.close();
                if (serverSocket != null) serverSocket.close();
                System.out.println("服务器连接关闭");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

// 客户端
public class TCPClient {
    public static void main(String[] args) {
        Socket socket = null;
        OutputStream out = null;
        InputStream in = null;
        try {
            // 创建Socket,连接服务器,这里隐含了三次握手的过程
            socket = new Socket("127.0.0.1", 8888);
            System.out.println("连接服务器成功");
            
            // 获取输入流和输出流
            out = socket.getOutputStream();
            in = socket.getInputStream();
            
            // 向服务器发送数据
            String data = "Hello, Server!";
            out.write(data.getBytes());
            out.flush();
            
            // 读取服务器返回的数据
            byte[] buffer = new byte[1024];
            int len = in.read(buffer);
            System.out.println("收到服务器数据:" + new String(buffer, 0, len));
            
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                // 关闭资源,隐含了四次挥手的过程
                if (out != null) out.close();
                if (in != null) in.close();
                if (socket != null) socket.close();
                System.out.println("客户端连接关闭");
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

        在这两段代码中,当客户端执行new Socket("127.0.0.1", 8888)和服务器执行serverSocket.accept()时,底层会完成三次握手过程以建立连接。而当我们关闭 Socket 等资源时,底层则会进行四次挥手来终止连接。需要注意的是,三次握手和四次挥手的具体实现是在操作系统的 TCP/IP 协议栈中,Java 代码只是通过 API 触发了这些过程。


网站公告

今日签到

点亮在社区的每一天
去签到