Socket 是網路通訊的基石。本文系統介紹 Java Socket 程式設計,涵蓋 TCP/UDP 協定差異、客戶端/伺服端架構、多執行緒併發處理與完整程式碼範例。
| 模式 | 特點 | 典型應用 |
|---|---|---|
| 主機/終端 | 集中運算、管理 | 大型主機系統 |
| 客戶端/伺服器 (C/S) | 分散式運算、雙向通訊 | 資料庫、即時通訊 |
| 瀏覽器/伺服器 (B/S) | 跨平台、零安裝 | Web 應用 |
java.net.Socket:客戶端 Socket,發起連線java.net.ServerSocket:伺服端 Socket,監聽連線請求java.net.DatagramSocket:UDP 無連線通訊
// 客戶端
Socket socket = new Socket("伺服器IP", 連接埠);
OutputStream out = socket.getOutputStream(); // 發送資料
InputStream in = socket.getInputStream(); // 接收資料
// ... 讀寫操作 ...
socket.close();
// 伺服端
ServerSocket server = new ServerSocket(連接埠);
while (true) {
Socket client = server.accept(); // 阻塞等待連線
// 處理客戶請求(建議開啟新執行緒)
client.close();
}
server.close();
public class EchoServer {
private static final int PORT = 8888;
private static ExecutorService pool = Executors.newCachedThreadPool();
public static void main(String[] args) throws IOException {
try (ServerSocket server = new ServerSocket(PORT)) {
System.out.println("伺服器啟動,監聽埠口: " + PORT);
while (true) {
Socket client = server.accept();
pool.execute(new ClientHandler(client));
}
}
}
static class ClientHandler implements Runnable {
private Socket socket;
ClientHandler(Socket socket) { this.socket = socket; }
@Override
public void run() {
try (BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream(), "UTF-8"));
PrintWriter out = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true)) {
String msg;
while ((msg = in.readLine()) != null) {
System.out.println("收到: " + msg);
if ("bye".equalsIgnoreCase(msg)) break;
out.println("Echo: " + msg);
}
} catch (IOException e) {
e.printStackTrace();
} finally {
try { socket.close(); } catch (IOException ignored) {}
}
}
}
}
public class EchoClient {
public static void main(String[] args) throws IOException {
try (Socket socket = new Socket("localhost", 8888);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream(), "UTF-8"));
PrintWriter out = new PrintWriter(
new OutputStreamWriter(socket.getOutputStream(), "UTF-8"), true);
BufferedReader console = new BufferedReader(
new InputStreamReader(System.in))) {
String input;
while ((input = console.readLine()) != null) {
out.println(input);
String response = in.readLine();
System.out.println("伺服器回應: " + response);
if ("bye".equalsIgnoreCase(input)) break;
}
}
}
}
適用於即時性要求高、可容忍封包遺失的場景(如視訊串流、DNS 查詢):
// 發送端
DatagramSocket socket = new DatagramSocket();
byte[] data = "Hello UDP".getBytes();
DatagramPacket packet = new DatagramPacket(data, data.length, InetAddress.getByName("localhost"), 9999);
socket.send(packet);
// 接收端
DatagramSocket server = new DatagramSocket(9999);
byte[] buffer = new byte[1024];
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
server.receive(packet);
String msg = new String(packet.getData(), 0, packet.getLength());
BufferedReader/PrintWriter 處理文字,DataInputStream/DataOutputStream 處理二進制ExecutorService 避免頻繁建立/銷毀執行緒socket.setSoTimeout(毫秒) 防止讀取無限阻塞java.nio.channels)SSLSocket)