Java中ServerSocket的用法 詳解服務端Socket

serversocket 是 Java 中用于監聽客戶端連接的核心類,其核心使用步驟包括:1. 創建 serversocket 并綁定端口;2. 調用 accept() 方法監聽并接受連接;3. 通過 socket 的輸入輸出流進行通信;4. 關閉資源。為應對高并發,可采用線程池或 nio 技術提升性能;bind() 方法用于指定綁定的 ip 和端口;backlog 參數控制連接請求隊列長度;setsotimeout() 方法可設置 accept() 的超時時間。

Java中ServerSocket的用法 詳解服務端Socket

服務端Socket,說白了,就是Java里 ServerSocket 這玩意兒。它負責監聽客戶端的連接請求,然后像個老鴇一樣,把連接“分配”給其他的 Socket 去處理。簡單來說,ServerSocket 負責接客,真正干活的是接到的 Socket。

Java中ServerSocket的用法 詳解服務端Socket

解決方案

Java中ServerSocket的用法 詳解服務端Socket

想用好 ServerSocket,得先理解它的幾個關鍵步驟:

立即學習Java免費學習筆記(深入)”;

  1. 創建 ServerSocket: 這就像開店選址,你得指定一個端口號,讓客戶端能找到你。比如 ServerSocket serverSocket = new ServerSocket(8080); 這就在8080端口開了個店。
  2. 監聽連接: serverSocket.accept() 這步很重要,它會阻塞程序,直到有客戶端來連接。就像店員在門口等著客人上門。accept() 方法會返回一個新的 Socket 對象,這個 Socket 就代表了和客戶端的連接。
  3. 處理連接: 拿到 Socket 對象后,就可以通過它的輸入輸出流和客戶端通信了。這部分邏輯可以放在一個新的線程里處理,避免阻塞主線程。
  4. 關閉連接: 通信完畢,記得關閉 Socket 和 ServerSocket,釋放資源。不然你的服務器遲早會被耗死。

一個簡單的例子:

Java中ServerSocket的用法 詳解服務端Socket

import java.net.*; import java.io.*;  public class SimpleServer {     public static void main(String[] args) throws IOException {         ServerSocket serverSocket = null;         try {             serverSocket = new ServerSocket(8080);             System.out.println("Server started on port 8080");              while (true) {                 Socket clientSocket = serverSocket.accept();                 System.out.println("Client connected: " + clientSocket.getInetAddress().getHostAddress());                  // 處理客戶端連接,可以放到單獨的線程中                 new Thread(() -> {                     try (                         PrintWriter out = new PrintWriter(clientSocket.getOutputStream(), true);                         BufferedReader in = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));                     ) {                         String inputLine;                         while ((inputLine = in.readLine()) != null) {                             System.out.println("Received: " + inputLine);                             out.println("Server received: " + inputLine); // Echo back to client                         }                         System.out.println("Client disconnected: " + clientSocket.getInetAddress().getHostAddress());                     } catch (IOException e) {                         e.printStackTrace();                     } finally {                         try {                             clientSocket.close();                         } catch (IOException e) {                             e.printStackTrace();                         }                     }                 }).start();             }         } catch (IOException e) {             System.err.println("Could not listen on port: 8080.");             System.exit(1);         } finally {             if (serverSocket != null) {                 try {                     serverSocket.close();                 } catch (IOException e) {                     e.printStackTrace();                 }             }         }     } }

這個例子里,服務器會一直監聽 8080 端口,每當有客戶端連接,就創建一個新的線程來處理。每個線程負責讀取客戶端發來的數據,然后把數據原樣返回給客戶端。

如何處理大量并發連接?

單線程的 ServerSocket 肯定扛不住高并發。一個比較常見的做法是使用線程池。每當 ServerSocket 接受到一個新的連接,就從線程池里取出一個線程來處理。這樣可以避免頻繁創建和銷毀線程的開銷。

另外,還可以考慮使用非阻塞 I/O(NIO)。NIO 允許一個線程同時管理多個連接,大大提高了服務器的并發能力。像 Netty 這樣的框架,就是基于 NIO 實現的。

ServerSocket 的 bind() 方法有什么用?

bind() 方法用于將 ServerSocket 綁定到一個特定的地址和端口。如果你不顯式調用 bind(),那么在創建 ServerSocket 的時候,系統會自動選擇一個可用的端口。

有時候,你可能需要將 ServerSocket 綁定到一個特定的 IP 地址。比如,你的服務器有多個網卡,你希望 ServerSocket 只監聽某個網卡上的連接。這時候,就可以使用 bind() 方法。

ServerSocket serverSocket = new ServerSocket(); SocketAddress socketAddress = new InetSocketAddress("192.168.1.100", 8080); serverSocket.bind(socketAddress);

這段代碼會將 ServerSocket 綁定到 IP 地址為 192.168.1.100 的網卡的 8080 端口。

ServerSocket 的 backlog 參數是什么意思?

backlog 參數指定了服務器可以接受的最大連接請求隊列的長度。當服務器忙于處理其他連接時,新的連接請求會被放入這個隊列中等待。如果隊列滿了,新的連接請求會被拒絕。

backlog 參數的值通常由操作系統決定,不同的操作系統有不同的默認值。你可以通過 ServerSocket 的構造函數來指定 backlog 的值。

ServerSocket serverSocket = new ServerSocket(8080, 100); // backlog = 100

但是,即使你指定了 backlog 的值,操作系統也可能會忽略你的設置,使用自己的默認值。

如何設置 ServerSocket 的超時時間?

有時候,你可能希望 ServerSocket 在一段時間內沒有收到任何連接請求就自動關閉。這時候,可以設置 ServerSocket 的超時時間。

Java 并沒有直接提供設置 ServerSocket 超時時間的方法。但是,你可以通過設置 Socket 的超時時間來實現類似的效果。

ServerSocket serverSocket = new ServerSocket(8080); serverSocket.setSoTimeout(5000); // 設置超時時間為 5 秒  try {     Socket clientSocket = serverSocket.accept();     // ... } catch (SocketTimeoutException e) {     System.out.println("Timeout occurred"); }

這段代碼會設置 ServerSocket 的超時時間為 5 秒。如果在 5 秒內沒有收到任何連接請求,accept() 方法會拋出一個 SocketTimeoutException 異常。

需要注意的是,setSoTimeout() 方法設置的是 Socket 的超時時間,而不是 ServerSocket 的超時時間。但是,由于 accept() 方法返回的是一個 Socket 對象,所以設置 Socket 的超時時間可以間接實現 ServerSocket 的超時效果。

? 版權聲明
THE END
喜歡就支持一下吧
點贊15 分享