首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java TCP Socket 通訊入門:單客戶端雙向聊天室實現

     編輯:Java 相關知識

架構概覽

經典一對一阻塞 I/O 模型:

  • Server:ServerSocket.accept() 阻塞等待連接,獲得 Socket 後雙向收發文本行。
  • Client:new Socket(host, port) 主動連接,雙向收發文本行。
  • 協議:以換行符 \n 為邊界,輸入 end 結束會話。

服務端代碼 (SocketService)

package com.fan.socket;

import java.io.*;
import java.net.*;

public class SocketService {
    public static void main(String[] args) {
        new SocketService().startServer();
    }

    public void startServer() {
        try (ServerSocket server = new ServerSocket(4800)) {
            System.out.println("Server 啟動,監聽 4800...");

            try (Socket client = server.accept();
                 BufferedReader in = new BufferedReader(new InputStreamReader(client.getInputStream()));
                 PrintWriter out = new PrintWriter(client.getOutputStream(), true);
                 BufferedReader console = new BufferedReader(new InputStreamReader(System.in))) {

                System.out.println("Client 已連接: " + client.getInetAddress());

                String line;
                // 先讀客戶端第一條
                System.out.println("Client: " + in.readLine());

                // 主循環:控制台讀入 → 發送給客戶端 → 讀客戶端回覆
                while ((line = console.readLine()) != null) {
                    if ("end".equalsIgnoreCase(line)) break;
                    out.println(line);
                    System.out.println("Server: " + line);
                    System.out.println("Client: " + in.readLine());
                }
            }
        } catch (IOException e) {
            System.err.println("Server 異常: " + e.getMessage());
        }
    }
}

客戶端代碼 (SocketClient)

package com.fan.socket;

import java.io.*;
import java.net.*;

public class SocketClient {
    public static void main(String[] args) {
        try (Socket socket = new Socket("127.0.0.1", 4800);
             BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
             PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
             BufferedReader console = new BufferedReader(new InputStreamReader(System.in))) {

            System.out.println("Client 啟動,連接 Server...");

            String line;
            while ((line = console.readLine()) != null) {
                if ("end".equalsIgnoreCase(line)) break;
                out.println(line);
                System.out.println("Client: " + line);
                System.out.println("Server: " + in.readLine());
            }
        } catch (IOException e) {
            System.err.println("Client 異常: " + e.getMessage());
        }
    }
}

運行演示

# Terminal 1: Server
Server 啟動,監聽 4800...
Client 已連接: /127.0.0.1
Client: Hello Server
Server: Hi Client
Client: How are you?
Server: Fine, thanks
Client: end

# Terminal 2: Client
Client 啟動,連接 Server...
Client: Hello Server
Server: Hi Client
Client: How are you?
Server: Fine, thanks
Client: end

關鍵點解析

擴展練習

  1. 將 Server 改為 while(true){ new Thread(new ClientHandler(socket)).start(); } 支持多客戶端。
  2. 加入心跳機制:雙方定時發送 PING/PONG 檢測連接存活。
  3. 使用 ObjectOutputStream/ObjectInputStream 傳輸 Java 對象(注意 serialVersionUID)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved
點說明
PrintWriter(autoFlush=true)構造函數第二參數 true 使 println 自動 flush,避免緩衝導致對端收不到數據
try-with-resourcesJDK 7+ 自動關閉流與 Socket,異常時也能釋放資源
阻塞模型限制單線程只能服務一個客戶端;生產環境需多線程/線程池或 NIO (Netty)
協議設計文本行協議簡單但無法傳輸二進制/含換行符數據;實際項目建議定長/分隔符/序列化協議