java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > java短连接、长连接

java短连接、长连接的详细说明

作者:泽553180

短连接一般只会在client/server间传递一次请求操作,对于频繁请求资源的客户端适合使用长连接,这篇文章主要介绍了java短连接、长连接的详细说明,需要的朋友可以参考下

前言

在网络通信中,短连接(Short Connection)是指客户端与服务器建立连接后,仅完成一次或几次数据交互就立即断开连接的通信方式。

以下是关于短链接的详细说明:

一、短链接的核心特点

连接短暂
数据传输完成后立即关闭连接(如 HTTP 请求响应后断开)。

单向请求
通常由客户端主动发起请求,服务器响应后结束(无服务器主动推送)。

轻量级
无需维护连接状态,资源占用低

二、短链接的常见问题与解决方案

  1. 连接建立开销

    • 问题:每次请求需重新进行 TCP 三次握手,影响高并发性能。
    • 解决方案
      • 使用 HTTP/2 协议复用连接(长链接优化)。
      • 对频繁请求的接口使用长链接。
  2. 数据完整性

    • 问题:短链接可能因网络问题导致数据截断。
    • 解决方案
      • 设计请求 / 响应协议时添加校验机制(如 MD5 签名)。
      • 对大数据分块传输并验证。

三、典型应用场景

在网络通信中,长链接(Long Connection)是指客户端与服务器建立连接后,保持该连接处于打开状态,允许双方在较长时间内持续进行数据交互,而不是每次通信后立即断开连接。

以下是关于长链接的详细说明:

一、长链接的核心特点

连接持久化
连接建立后不会主动关闭,可多次发送 / 接收数据(如即时聊天、实时推送)。

节省资源
避免频繁创建和销毁连接的开销(短链接每次请求都需重新建立 TCP 三次握手)。

双向通信
支持服务器主动向客户端推送消息(如消息通知、实时数据更新)。

二、长链接的常见问题与解决方案

  1. 连接断开问题

    • 原因:网络波动、服务器重启、防火墙超时。
    • 解决方案
      • 实现心跳机制(客户端定期发送心跳包,服务器响应确认存活)。
      • 设置合理的超时重连策略。
  2. 资源消耗

    • 问题:大量长链接可能占用服务器内存和端口资源。
    • 解决方案
      • 使用线程池或 NIO(非阻塞 IO)优化服务器性能。
      • 对空闲连接设置超时关闭(如 30 分钟无活动则断开)。
  3. 粘包 / 拆包问题

    • 问题:TCP 是流式传输,可能导致多条消息混合或被截断。
    • 解决方案
      • 定义消息协议(如固定长度头部 + 消息体)。
      • 使用DataInputStream按字节读取并解析。

三、典型应用场景

短连接和长连接的比较

 现在举一个长连接的代码示例:实现多用户之间的私聊

import java.io.*;
import java.net.*;
import java.util.*;
 
// 服务器类
public class ChatServer {
    private static final int PORT = 12345;
    private static Map<String, PrintWriter> clients = new HashMap<>();
 
    public static void main(String[] args) {
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            System.out.println("Chat Server is running on port " + PORT);
            while (true) {
                new ClientHandler(serverSocket.accept()).start();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
 
    // 客户端处理类
    private static class ClientHandler extends Thread {
        private Socket socket;
        private PrintWriter out;
        private BufferedReader in;
        private String clientName;
 
        public ClientHandler(Socket socket) {
            this.socket = socket;
        }
 
        @Override
        public void run() {
            try {
                out = new PrintWriter(socket.getOutputStream(), true);
                in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
 
                // 获取客户端名称
                clientName = in.readLine();
                clients.put(clientName, out);
                System.out.println(clientName + " has joined the chat.");
 
                String inputLine;
                while ((inputLine = in.readLine()) != null) {
                    if (inputLine.startsWith("/msg")) {
                        String[] parts = inputLine.split(" ", 3);
                        if (parts.length == 3) {
                            String recipient = parts[1];
                            String message = parts[2];
                            sendPrivateMessage(clientName, recipient, message);
                        }
                    }
                }
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                try {
                    socket.close();
                    clients.remove(clientName);
                    System.out.println(clientName + " has left the chat.");
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
 
        // 发送私聊消息
        private void sendPrivateMessage(String sender, String recipient, String message) {
            PrintWriter recipientWriter = clients.get(recipient);
            if (recipientWriter != null) {
                recipientWriter.println(sender + " whispers: " + message);
            } else {
                out.println("User " + recipient + " not found.");
            }
        }
    }
} 
-----------------------------------------------------------------------------
import java.io.*;
import java.net.*;
import java.util.Scanner;
 
// 客户端类
public class ChatClient {
    private static final String SERVER_ADDRESS = "localhost";
    private static final int PORT = 12345;
 
    public static void main(String[] args) {
        try (Socket socket = new Socket(SERVER_ADDRESS, PORT);
             PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
             BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
             Scanner scanner = new Scanner(System.in)) {
 
            System.out.print("Enter your name: ");
            String name = scanner.nextLine();
            out.println(name);
 
            // 启动一个线程来接收服务器消息
            new Thread(() -> {
                try {
                    String inputLine;
                    while ((inputLine = in.readLine()) != null) {
                        System.out.println(inputLine);
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }).start();
 
            // 读取用户输入并发送消息
            String input;
            while (scanner.hasNextLine()) {
                input = scanner.nextLine();
                out.println(input);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}       

代码中体现长连接的部分

服务器端(ChatServer)

客户端(ChatClient)

综上所述,代码通过不断地在连接上进行数据的读写操作,保持了客户端和服务器之间的连接,属于长连接的实现方式。

总结

到此这篇关于java短连接、长连接详细说明的文章就介绍到这了,更多相关java短连接、长连接内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文