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

現(xiàn)在舉一個(gè)長(zhǎng)連接的代碼示例:實(shí)現(xiàn)多用戶之間的私聊
import java.io.*;
import java.net.*;
import java.util.*;
// 服務(wù)器類
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);
// 啟動(dòng)一個(gè)線程來(lái)接收服務(wù)器消息
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)長(zhǎng)連接的部分
服務(wù)器端(ChatServer)
- 持續(xù)監(jiān)聽(tīng):
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(); }
服務(wù)器通過(guò)ServerSocket監(jiān)聽(tīng)指定端口,while (true)循環(huán)會(huì)持續(xù)不斷地接受新的客戶端連接請(qǐng)求。一旦有新的客戶端連接進(jìn)來(lái),就會(huì)為其創(chuàng)建一個(gè)ClientHandler線程進(jìn)行處理,整個(gè)過(guò)程中服務(wù)器的監(jiān)聽(tīng)狀態(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); } } }
每個(gè)ClientHandler線程負(fù)責(zé)與一個(gè)客戶端進(jìn)行通信。while ((inputLine = in.readLine()) != null)循環(huán)會(huì)持續(xù)讀取客戶端發(fā)送過(guò)來(lái)的消息,只要客戶端沒(méi)有主動(dòng)斷開(kāi)連接,這個(gè)循環(huán)就會(huì)一直運(yùn)行,從而保持與客戶端的連接處于活躍狀態(tài)。
客戶端(ChatClient)
- 持續(xù)接收消息:
java
客戶端啟動(dòng)一個(gè)單獨(dú)的線程來(lái)持續(xù)接收服務(wù)器發(fā)送過(guò)來(lái)的消息。只要服務(wù)器沒(méi)有主動(dòng)斷開(kāi)連接,這個(gè)線程就會(huì)一直運(yùn)行,不斷地從輸入流中讀取數(shù)據(jù),以此維持與服務(wù)器的連接。 - 持續(xù)發(fā)送消息:
java
String input; while (scanner.hasNextLine()) { input = scanner.nextLine(); out.println(input); }
客戶端通過(guò)while (scanner.hasNextLine())循環(huán)持續(xù)讀取用戶的輸入,并將其發(fā)送給服務(wù)器。只要用戶持續(xù)輸入消息,客戶端就會(huì)持續(xù)向服務(wù)器發(fā)送數(shù)據(jù),連接也會(huì)一直保持。
綜上所述,代碼通過(guò)不斷地在連接上進(jìn)行數(shù)據(jù)的讀寫(xiě)操作,保持了客戶端和服務(wù)器之間的連接,屬于長(zhǎng)連接的實(shí)現(xiàn)方式。
總結(jié)
到此這篇關(guān)于java短連接、長(zhǎng)連接詳細(xì)說(shuō)明的文章就介紹到這了,更多相關(guān)java短連接、長(zhǎng)連接內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot內(nèi)嵌Tomcat安全漏洞修復(fù)方式
針對(duì)CVE-2020-1938漏洞,建議升級(jí)Tomcat至安全版本以避免受影響,影響版本包括:Apache Tomcat 9.x小于9.0.31、Apache Tomcat 8.x小于8.5.51、Apache Tomcat 7.x小于7.0.100及Apache Tomcat 6.x,2024-10-10
Spring中BeanFactory和ApplicationContext的作用和區(qū)別(推薦)
這篇文章主要介紹了Spring中BeanFactory和ApplicationContext的作用和區(qū)別,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-09-09
Spring?IOC容器基于XML外部屬性文件的Bean管理
這篇文章主要為大家介紹了Spring?IOC容器Bean管理XML外部屬性文件,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-05-05
HelloSpringMVC配置版實(shí)現(xiàn)步驟解析
這篇文章主要介紹了HelloSpringMVC配置版實(shí)現(xiàn)步驟解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-09-09
Java輕松實(shí)現(xiàn)Excel轉(zhuǎn)PDF的實(shí)戰(zhàn)指南
這篇文章主要介紹了兩種將Excel轉(zhuǎn)換為PDF的方法,第一種使用Spire.XLS免費(fèi)版,第二種方法(破解版)支持多頁(yè)轉(zhuǎn)換,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以了解下2026-03-03
MyBatis之動(dòng)態(tài)SQL和緩存使用及說(shuō)明
這篇文章主要介紹了MyBatis之動(dòng)態(tài)SQL和緩存使用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2026-05-05
Struts2源碼分析之ParametersInterceptor攔截器
這篇文章主要介紹了Struts2源碼分析之ParametersInterceptor攔截器,ParametersInterceptor攔截器其主要功能是把ActionContext中的請(qǐng)求參數(shù)設(shè)置到ValueStack中,,需要的朋友可以參考下2019-06-06
手把手教你如何在idea中搭建SpringBoot項(xiàng)目
這篇文章主要介紹了如何搭建一個(gè)SpringBoot項(xiàng)目,包括環(huán)境準(zhǔn)備、創(chuàng)建新項(xiàng)目、探索項(xiàng)目結(jié)構(gòu)以及展望未來(lái),通過(guò)詳細(xì)的步驟和實(shí)用的技巧,幫助開(kāi)發(fā)者快速上手SpringBoot開(kāi)發(fā),文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2025-02-02

