C/S 架構採用基於連接的網絡通信模式:首先定義通信協議,創建 Socket 建立可靠連接,然後在連接上傳輸數據。典型的「請求-應答」流程如下:
ServerSocket 處理客戶機連接請求。當客戶機連接時,分配新的 Socket 對象處理該客戶機通信,主線程繼續監聽新連接。
Server 對象本身是線程,run() 方法無限循環監聽連接Socket 實例與 Connection 線程對象Connection 初始化通信流並處理所有與該客戶機的通信Socket 連接服務器DataInputStream 讀取數據、PrintStream 寫入數據// Server.java
import java.io.*;
import java.net.*;
public class Server extends Thread {
public final static int Default_Port = 6543;
protected int port;
protected ServerSocket listen_socket;
public static void fail(Exception e, String msg) {
System.err.println(msg + ": " + e);
System.exit(1);
}
public Server(int port) {
if (port == 0) port = Default_Port;
this.port = port;
try {
listen_socket = new ServerSocket(port);
} catch (IOException e) {
fail(e, "Exception creating server socket");
}
System.out.println("Server: listening on port " + port);
this.start();
}
public void run() {
try {
while (true) {
Socket client_socket = listen_socket.accept();
Connection c = new Connection(client_socket);
}
} catch (IOException e) {
fail(e, "Exception while listening for connections");
}
}
public static void main(String args[]) {
int port = 0;
if (args.length == 1) {
try { port = Integer.parseInt(args[0]); }
catch (NumberFormatException e) { port = 0; }
}
new Server(port);
}
}
class Connection extends Thread {
protected Socket client;
protected DataInputStream in;
protected PrintStream out;
public Connection(Socket client_socket) {
client = client_socket;
try {
in = new DataInputStream(client.getInputStream());
out = new PrintStream(client.getOutputStream());
} catch (IOException e) {
try { client.close(); } catch (IOException e2) {}
System.err.println("Exception while getting socket stream: " + e);
return;
}
this.start();
}
public void run() {
String line;
StringBuffer revline;
int len;
try {
for (;;) {
line = in.readLine();
if (line == null) break;
len = line.length();
revline = new StringBuffer(len);
for (int i = len - 1; i >= 0; i--)
revline.append(line.charAt(i));
out.println(revline);
}
} catch (IOException e) {}
finally {
try { client.close(); } catch (IOException e2) {}
}
}
}
// Client.java
import java.io.*;
import java.net.*;
public class Client {
public static final int Default_Port = 6543;
public static final void usage() {
System.out.println("Usage: java Client [host] [port]");
System.exit(0);
}
public static void main(String args[]) {
int port = Default_Port;
Socket s = null;
if ((args.length != 1) && (args.length != 2)) usage();
if (args.length == 2) {
try { port = Integer.parseInt(args[1]); }
catch (NumberFormatException e) { usage(); }
}
try {
s = new Socket(args[0], port);
DataInputStream sin = new DataInputStream(s.getInputStream());
PrintStream sout = new PrintStream(s.getOutputStream());
DataInputStream in = new DataInputStream(System.in);
System.out.println("Connected to " + s.getInetAddress() + ":" + s.getPort());
String line;
for (;;) {
System.out.print(" >");
System.out.flush();
line = in.readLine();
if (line == null) break;
sout.println(line);
line = sin.readLine();
if (line == null) {
System.out.println("Connection closed by server.");
break;
}
System.out.println(line);
}
} catch (IOException e) {
System.err.println(e);
} finally {
try { if (s != null) s.close(); } catch (IOException e2) {}
}
}
}