本文提供基於 Java Socket 的客戶端登入驗證完整代碼,實現鍵盤輸入用戶名、伺服器端檔案驗證、最多三次嘗試限制、多執行緒併發處理等核心功能。
user.txt 檔案讀取合法用戶列表進行驗證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();
}
}
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("驗證失敗");
}
}
}
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();
}
}
}
Socket 連接 → 獲取輸出流發送用戶名 → 獲取輸入流接收回應ServerSocket.accept() 阻塞等待 → 建立執行緒處理 → 讀取輸入流 → 驗證 → 寫入輸出流回應伺服器主執行緒只負責 accept() 接受連線,每個連線立即派發給獨立 Thread 處理,實現多客戶端同時驗證互不阻塞。
break 跳出驗證迴圈,失敗則繼續下一次嘗試程式碼中使用 FileReader("user.txt") 讀取本地檔案,實際專案中只需替換為資料庫查詢 (JDBC/JPA/MyBatis) 即可,業務邏輯層完全解耦。
admin
zhangsan
lisi
wangwu
伺服器端輸出:
192.168.33.50...........connect
zhangsan:已登入
客戶端輸出:
Server info: zhangsan:歡迎登入
本實例展示了 Java Socket 網路程式設計的經典模式:多執行緒伺服器 + 狀態控制 + 簡單協議。雖然現代開發多使用 HTTP/REST/gRPC,但理解 Socket 基礎對排查網路問題、設計自定義協議仍有重要價值。