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

Java Socket 實現客戶端登入驗證完整代碼實例

     編輯:Java 相關知識

Java Socket 客戶端/伺服器端用戶名驗證完整實現

本文提供基於 Java Socket 的客戶端登入驗證完整代碼,實現鍵盤輸入用戶名、伺服器端檔案驗證、最多三次嘗試限制、多執行緒併發處理等核心功能。

功能需求

  • 客戶端從鍵盤輸入用戶名發送給伺服器
  • 伺服器從 user.txt 檔案讀取合法用戶列表進行驗證
  • 用戶存在:伺服器顯示「xxx已登入」,客戶端顯示「xxx,歡迎登入」
  • 用戶不存在:伺服器顯示「xxx嘗試登入」,客戶端顯示「xxx,用戶名不存在」
  • 最多允許 3 次嘗試,防止暴力破解

完整代碼實現

客戶端 Client 類

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

class Client {
    public static void main(String[] args) throws Exception {
        Socket socket = new Socket("192.168.33.1", 10008);
        
        BufferedReader keyboard = new BufferedReader(
            new InputStreamReader(System.in));
        PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
        BufferedReader in = new BufferedReader(
            new InputStreamReader(socket.getInputStream()));
        
        // 最多嘗試 3 次
        for (int attempt = 0; attempt < 3; attempt++) {
            String username = keyboard.readLine();
            if (username == null) break;
            
            out.println(username);
            String response = in.readLine();
            System.out.println("Server info: " + response);
            
            if (response.contains("歡迎登入")) break; // 登入成功結束
        }
        
        keyboard.close();
        socket.close();
    }
}

伺服器端 ServerThread 處理執行緒

class ServerThread implements Runnable {
    private Socket socket;
    
    ServerThread(Socket socket) {
        this.socket = socket;
    }
    
    public void run() {
        String clientIP = socket.getInetAddress().getHostAddress();
        System.out.println(clientIP + "...........connect");
        
        try {
            // 每個客戶端最多驗證 3 次
            for (int attempt = 0; attempt < 3; attempt++) {
                BufferedReader in = new BufferedReader(
                    new InputStreamReader(socket.getInputStream()));
                String username = in.readLine();
                if (username == null) break;
                
                // 讀取用戶檔案 (實際專案應使用資料庫)
                BufferedReader userFile = new BufferedReader(
                    new FileReader("user.txt"));
                PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
                
                String line;
                boolean found = false;
                while ((line = userFile.readLine()) != null) {
                    if (line.equals(username)) {
                        found = true;
                        break;
                    }
                }
                userFile.close();
                
                if (found) {
                    System.out.println(username + ":已登入");
                    out.println(username + ":歡迎登入");
                    break; // 驗證成功,結束嘗試
                } else {
                    System.out.println(username + ":嘗試登入");
                    out.println(username + ":用戶名不存在");
                }
            }
            socket.close();
        } catch (Exception e) {
            throw new RuntimeException("驗證失敗");
        }
    }
}

伺服器主類 Server

class Server {
    public static void main(String[] args) throws Exception {
        ServerSocket serverSocket = new ServerSocket(10008);
        while (true) {
            Socket socket = serverSocket.accept();
            new Thread(new ServerThread(socket)).start();
        }
    }
}

關鍵技術點解析

1. Socket 通訊流程

  • 客戶端:Socket 連接 → 獲取輸出流發送用戶名 → 獲取輸入流接收回應
  • 伺服器:ServerSocket.accept() 阻塞等待 → 建立執行緒處理 → 讀取輸入流 → 驗證 → 寫入輸出流回應

2. 多執行緒併發模型

伺服器主執行緒只負責 accept() 接受連線,每個連線立即派發給獨立 Thread 處理,實現多客戶端同時驗證互不阻塞。

3. 狀態控制邏輯

  • 雙層迴圈:外層伺服器持續接受新連線,內層每個連線最多 3 次驗證
  • 成功即 break 跳出驗證迴圈,失敗則繼續下一次嘗試
  • 客戶端同樣限制 3 次迴圈,收到歡迎訊息即結束

4. 資料來源擴展性

程式碼中使用 FileReader("user.txt") 讀取本地檔案,實際專案中只需替換為資料庫查詢 (JDBC/JPA/MyBatis) 即可,業務邏輯層完全解耦。

user.txt 範例格式


admin
zhangsan
lisi
wangwu

執行結果示例


伺服器端輸出:
192.168.33.50...........connect
zhangsan:已登入

客戶端輸出:
Server info: zhangsan:歡迎登入

安全性與改進建議

  • 密碼驗證:當前僅驗證用戶名,實際應加入密碼雜湊比對 (BCrypt/Argon2)
  • 加密傳輸:使用 SSL/TLS (SSLSocket) 防止竊聽
  • 鎖定機制:連續失敗達標後鎖定 IP/帳號一段時間
  • 資料庫連線池:使用 HikariCP 管理連線,避免頻繁開關
  • 非阻塞 I/O:高併發場景考慮 Netty 或 NIO Selector 模型
  • 日誌記錄:整合 SLF4J/Logback 記錄登入審計日誌

總結

本實例展示了 Java Socket 網路程式設計的經典模式:多執行緒伺服器 + 狀態控制 + 簡單協議。雖然現代開發多使用 HTTP/REST/gRPC,但理解 Socket 基礎對排查網路問題、設計自定義協議仍有重要價值。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved