在網路程式設計中,伺服器不會主動發起連線,而是被動地監聽特定埠口,等待客戶端的連線請求。Java 提供 ServerSocket 類別來實作這項功能。一個典型的簡易 Web 伺服器範例如下:
class SimpleWebServer {
public static void main(String args[]) {
ServerSocket serverSocket = null;
Socket clientSocket = null;
int connects = 0;
try {
// 建立伺服器 Socket,綁定埠 80,佇列長度 5
serverSocket = new ServerSocket(80, 5);
while (connects < 5) {
// 阻塞等待客戶端連線
clientSocket = serverSocket.accept();
// 處理客戶請求
serviceClient(clientSocket);
connects++;
}
serverSocket.close();
} catch (IOException ioe) {
System.out.println("SimpleWebServer 錯誤: " + ioe);
}
}
public static void serviceClient(Socket client) throws IOException {
DataInputStream inbound = null;
DataOutputStream outbound = null;
try {
// 取得輸入/輸出串流
inbound = new DataInputStream(client.getInputStream());
outbound = new DataOutputStream(client.getOutputStream());
// 準備 HTTP 回應內容
StringBuffer buffer = prepareOutput();
String inputLine;
// 讀取 HTTP 請求頭,直到空行
while ((inputLine = inbound.readLine()) != null) {
if (inputLine.equals("")) {
outbound.writeBytes(buffer.toString());
break;
}
}
} finally {
// 清理資源
System.out.println("清理連線: " + client);
if (outbound != null) outbound.close();
if (inbound != null) inbound.close();
if (client != null) client.close();
}
}
private static StringBuffer prepareOutput() {
StringBuffer sb = new StringBuffer();
sb.append("HTTP/1.0 200 OK\r\n");
sb.append("Content-Type: text/html\r\n\r\n");
sb.append("Hello from SimpleWebServer
");
return sb;
}
}
ServerSocket serverSocket = new ServerSocket(80, 5);
Socket clientSocket = serverSocket.accept();
此方法會阻塞執行緒,直到有客戶端連線進來。它會從佇列中取出一個連線,並回傳一個新的 Socket 物件,代表與該客戶端的專用通訊管道。原本的 ServerSocket 繼續保持開啟,繼續監聽新的連線請求。
取得客戶端 Socket 後,透過 getInputStream() 和 getOutputStream() 取得輸入/輸出串流,通常包裝為 DataInputStream/DataOutputStream 或 BufferedReader/PrintWriter 以便處理文字協定(如 HTTP)。
ServerSocket 並綁定埠口。accept() 進入阻塞等待。accept() 回傳專用 Socket。這種「一請求一執行緒」或「單執行緒循環」模型適合簡單教學或低併發場景。生產環境通常會結合執行緒池、NIO(Non-blocking I/O)或非同步 I/O 以提升擴展性。