在實作 Java 多執行緒 Socket 通訊時,常見問題是伺服器雖能接受連線,卻收不到客戶端傳送的字串。以下針對典型錯誤程式碼進行分析與修正。
ServerSocketMult 的 finally 區塊在 accept() 後立即呼叫 socket.close(),導致負責通訊的 Mult 執行緒尚未讀取資料時 Socket 已關閉。ClientSocketMultThread 的 threadcount 為靜態變數,多執行緒並發修改需加 synchronized。catch 區塊皆為空,導致錯誤無法追蹤。public class ServerSocketMult {
static final int PORT = 8080;
public static void main(String[] args) throws IOException {
ServerSocket s = new ServerSocket(PORT);
System.out.println("Server Started");
try {
while (true) {
Socket socket = s.accept();
System.out.println("Connection success!");
new Mult(socket); // 交由執行緒處理,主執行緒不關閉 socket
}
} catch (IOException e) {
e.printStackTrace();
} finally {
s.close();
}
}
}
class Mult extends Thread {
private Socket socket;
private BufferedReader in;
private PrintWriter out;
public Mult(Socket s) throws IOException {
socket = s;
in = new BufferedReader(new InputStreamReader(s.getInputStream()));
out = new PrintWriter(new OutputStreamWriter(s.getOutputStream()), true);
start();
}
public void run() {
System.out.println("print received ...");
try {
String str = in.readLine();
StringBuffer buffer = new StringBuffer();
while (str != null && !str.equals("END")) {
buffer.append(str);
str = in.readLine();
}
String value = buffer.toString();
out.println(value);
System.out.println("Receiving and echoing:" + value);
System.out.println("closing...");
} catch (IOException e) {
e.printStackTrace();
} finally {
try { socket.close(); } catch (IOException e) { e.printStackTrace(); }
}
}
}
class ClientSocketMultThread extends Thread {
// ... 省略部分欄位 ...
public synchronized static int threadCount() { return threadcount; }
public synchronized static void addThreadCount() { threadcount++; }
public synchronized static void descThreadCount() { threadcount--; }
// ... 建構子與 run() 中呼叫 descThreadCount() ...
}
修正後,伺服器能正確接收並回應客戶端訊息,多執行緒計數器亦正常運作。