使用套接字的基本客戶端和伺服器通訊
伺服器:啟動,並等待傳入連線
//Open a listening "ServerSocket" on port 1234.
ServerSocket serverSocket = new ServerSocket(1234);
while (true) {
// Wait for a client connection.
// Once a client connected, we get a "Socket" object
// that can be used to send and receive messages to/from the newly
// connected client
Socket clientSocket = serverSocket.accept();
// Here we'll add the code to handle one specific client.
}
伺服器:處理客戶端
我們將在一個單獨的執行緒中處理每個客戶端,以便多個客戶端可以同時與伺服器進行互動。只要客戶端數量較少(<< 1000 個客戶端,具體取決於作業系統體系結構和每個執行緒的預期負載),此技術就可以正常工作。
new Thread(() -> {
// Get the socket's InputStream, to read bytes from the socket
InputStream in = clientSocket.getInputStream();
// wrap the InputStream in a reader so you can read a String instead of bytes
BufferedReader reader = new BufferedReader(
new InputStreamReader(in, StandardCharsets.UTF_8));
// Read text from the socket and print line by line
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}).start();
客戶端:連線到伺服器併傳送訊息
// 127.0.0.1 is the address of the server (this is the localhost address; i.e.
// the address of our own machine)
// 1234 is the port that the server will be listening on
Socket socket = new Socket("127.0.0.1", 1234);
// Write a string into the socket, and flush the buffer
OutputStream outStream = socket.getOutputStream();
PrintWriter writer = new PrintWriter(
new OutputStreamWriter(outStream, StandardCharsets.UTF_8));
writer.println("Hello world!");
writer.flush();
關閉套接字和處理異常
上面的例子省略了一些使它們更容易閱讀的東西。
-
就像檔案和其他外部資源一樣,我們在完成作業系統時告訴作業系統非常重要。當我們完成套接字時,請呼叫
socket.close()
以正確關閉它。 -
套接字處理依賴於各種外部因素的 I / O(輸入/輸出)操作。例如,如果另一方突然斷開連線怎麼辦?如果有網路錯誤怎麼辦?這些事情是我們無法控制的。這就是許多套接字操作可能丟擲異常的原因,尤其是
IOException
。
因此,客戶端的更完整程式碼將是這樣的:
// "try-with-resources" will close the socket once we leave its scope
try (Socket socket = new Socket("127.0.0.1", 1234)) {
OutputStream outStream = socket.getOutputStream();
PrintWriter writer = new PrintWriter(
new OutputStreamWriter(outStream, StandardCharsets.UTF_8));
writer.println("Hello world!");
writer.flush();
} catch (IOException e) {
//Handle the error
}
基本伺服器和客戶端 - 完整示例
伺服器:
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class Server {
public static void main(String args[]) {
try (ServerSocket serverSocket = new ServerSocket(1234)) {
while (true) {
// Wait for a client connection.
Socket clientSocket = serverSocket.accept();
// Create and start a thread to handle the new client
new Thread(() -> {
try {
// Get the socket's InputStream, to read bytes
// from the socket
InputStream in = clientSocket.getInputStream();
// wrap the InputStream in a reader so you can
// read a String instead of bytes
BufferedReader reader = new BufferedReader(
new InputStreamReader(in, StandardCharsets.UTF_8));
// Read from the socket and print line by line
String line;
while ((line = reader.readLine()) != null) {
System.out.println(line);
}
}
catch (IOException e) {
e.printStackTrace();
} finally {
// This finally block ensures the socket is closed.
// A try-with-resources block cannot be used because
// the socket is passed into a thread, so it isn't
// created and closed in the same block
try {
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
}
catch (IOException e) {
e.printStackTrace();
}
}
}
客戶:
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.Socket;
import java.nio.charset.StandardCharsets;
public class Client {
public static void main(String args[]) {
try (Socket socket = new Socket("127.0.0.1", 1234)) {
// We'll reach this code once we've connected to the server
// Write a string into the socket, and flush the buffer
OutputStream outStream = socket.getOutputStream();
PrintWriter writer = new PrintWriter(
new OutputStreamWriter(outStream, StandardCharsets.UTF_8));
writer.println("Hello world!");
writer.flush();
} catch (IOException e) {
// Exception should be handled.
e.printStackTrace();
}
}
}