java短連接、長連接的詳細說明
前言
在網(wǎng)絡通信中,短連接(Short Connection)是指客戶端與服務器建立連接后,僅完成一次或幾次數(shù)據(jù)交互就立即斷開連接的通信方式。
以下是關于短鏈接的詳細說明:
一、短鏈接的核心特點
連接短暫
數(shù)據(jù)傳輸完成后立即關閉連接(如 HTTP 請求響應后斷開)。
單向請求
通常由客戶端主動發(fā)起請求,服務器響應后結束(無服務器主動推送)。
輕量級
無需維護連接狀態(tài),資源占用低
二、短鏈接的常見問題與解決方案
連接建立開銷
- 問題:每次請求需重新進行 TCP 三次握手,影響高并發(fā)性能。
- 解決方案:
- 使用 HTTP/2 協(xié)議復用連接(長鏈接優(yōu)化)。
- 對頻繁請求的接口使用長鏈接。
數(shù)據(jù)完整性
- 問題:短鏈接可能因網(wǎng)絡問題導致數(shù)據(jù)截斷。
- 解決方案:
- 設計請求 / 響應協(xié)議時添加校驗機制(如 MD5 簽名)。
- 對大數(shù)據(jù)分塊傳輸并驗證。
三、典型應用場景
- 網(wǎng)頁瀏覽:瀏覽器通過 HTTP 短鏈接請求網(wǎng)頁資源。
- 文件下載:通過 HTTP 短鏈接下載文件(如圖片、視頻)。
- API 調(diào)用:客戶端調(diào)用 RESTful API 獲取數(shù)據(jù)(如電商商品信息)。
- 登錄認證:客戶端發(fā)送登錄請求,服務器返回結果后斷開。
在網(wǎng)絡通信中,長鏈接(Long Connection)是指客戶端與服務器建立連接后,保持該連接處于打開狀態(tài),允許雙方在較長時間內(nèi)持續(xù)進行數(shù)據(jù)交互,而不是每次通信后立即斷開連接。
以下是關于長鏈接的詳細說明:
一、長鏈接的核心特點
連接持久化
連接建立后不會主動關閉,可多次發(fā)送 / 接收數(shù)據(jù)(如即時聊天、實時推送)。
節(jié)省資源
避免頻繁創(chuàng)建和銷毀連接的開銷(短鏈接每次請求都需重新建立 TCP 三次握手)。
雙向通信
支持服務器主動向客戶端推送消息(如消息通知、實時數(shù)據(jù)更新)。
二、長鏈接的常見問題與解決方案
連接斷開問題
- 原因:網(wǎng)絡波動、服務器重啟、防火墻超時。
- 解決方案:
- 實現(xiàn)心跳機制(客戶端定期發(fā)送心跳包,服務器響應確認存活)。
- 設置合理的超時重連策略。
資源消耗
- 問題:大量長鏈接可能占用服務器內(nèi)存和端口資源。
- 解決方案:
- 使用線程池或 NIO(非阻塞 IO)優(yōu)化服務器性能。
- 對空閑連接設置超時關閉(如 30 分鐘無活動則斷開)。
粘包 / 拆包問題
- 問題:TCP 是流式傳輸,可能導致多條消息混合或被截斷。
- 解決方案:
- 定義消息協(xié)議(如固定長度頭部 + 消息體)。
- 使用
DataInputStream按字節(jié)讀取并解析。
三、典型應用場景
- 即時通訊:微信、QQ 的消息推送。
- 實時監(jiān)控:股票行情、物聯(lián)網(wǎng)設備狀態(tài)上報。
- 在線協(xié)作:協(xié)同編輯文檔(如 Google Docs)。
- 游戲服務器:多人在線游戲的實時交互。
短連接和長連接的比較

現(xiàn)在舉一個長連接的代碼示例:實現(xiàn)多用戶之間的私聊
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();
}
}
}
// 發(fā)送私聊消息
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();
// 讀取用戶輸入并發(fā)送消息
String input;
while (scanner.hasNextLine()) {
input = scanner.nextLine();
out.println(input);
}
} catch (IOException e) {
e.printStackTrace();
}
}
} 代碼中體現(xiàn)長連接的部分
服務器端(ChatServer)
- 持續(xù)監(jiān)聽:
java
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(); }
服務器通過ServerSocket監(jiān)聽指定端口,while (true)循環(huán)會持續(xù)不斷地接受新的客戶端連接請求。一旦有新的客戶端連接進來,就會為其創(chuàng)建一個ClientHandler線程進行處理,整個過程中服務器的監(jiān)聽狀態(tài)是一直保持的。- 客戶端處理線程(ClientHandler):
java
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); } } }
每個ClientHandler線程負責與一個客戶端進行通信。while ((inputLine = in.readLine()) != null)循環(huán)會持續(xù)讀取客戶端發(fā)送過來的消息,只要客戶端沒有主動斷開連接,這個循環(huán)就會一直運行,從而保持與客戶端的連接處于活躍狀態(tài)。
客戶端(ChatClient)
- 持續(xù)接收消息:
java
客戶端啟動一個單獨的線程來持續(xù)接收服務器發(fā)送過來的消息。只要服務器沒有主動斷開連接,這個線程就會一直運行,不斷地從輸入流中讀取數(shù)據(jù),以此維持與服務器的連接。 - 持續(xù)發(fā)送消息:
java
String input; while (scanner.hasNextLine()) { input = scanner.nextLine(); out.println(input); }
客戶端通過while (scanner.hasNextLine())循環(huán)持續(xù)讀取用戶的輸入,并將其發(fā)送給服務器。只要用戶持續(xù)輸入消息,客戶端就會持續(xù)向服務器發(fā)送數(shù)據(jù),連接也會一直保持。
綜上所述,代碼通過不斷地在連接上進行數(shù)據(jù)的讀寫操作,保持了客戶端和服務器之間的連接,屬于長連接的實現(xiàn)方式。
總結
到此這篇關于java短連接、長連接詳細說明的文章就介紹到這了,更多相關java短連接、長連接內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot使用redis生成訂單號的實現(xiàn)示例
在電商系統(tǒng)中,生成唯一訂單號是常見需求,本文介紹如何利用SpringBoot和Redis實現(xiàn)訂單號的生成,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2024-09-09
詳解java CountDownLatch和CyclicBarrier在內(nèi)部實現(xiàn)和場景上的區(qū)別
這篇文章主要介紹了詳解java CountDownLatch和CyclicBarrier在內(nèi)部實現(xiàn)和場景上的區(qū)別,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05

