# Java 网络编程入门:实现简单的客户端 - 服务器通信

# 1. 需求理解

我们的目标是创建一个简单的客户端 - 服务器应用程序。服务器将监听特定端口,等待客户端连接。一旦客户端连接成功,服务器将接收客户端发送的消息,并将消息原样返回给客户端。客户端则负责连接到服务器,发送消息,并接收服务器的响应。

# 2. 代码实现

# 2.1 服务器端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.ServerSocket;
import java.net.Socket;

public class Server {
private static final int PORT = 12345;

public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("Server is listening on port " + PORT);

while (true) {
try (Socket socket = serverSocket.accept();
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
PrintWriter out = new PrintWriter(socket.getOutputStream(), true)) {

System.out.println("New client connected");

String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("Received from client: " + inputLine);
out.println("Server received: " + inputLine);
}
} catch (IOException e) {
System.err.println("Error handling client connection: " + e.getMessage());
}
}
} catch (IOException e) {
System.err.println("Could not listen on port " + PORT + ": " + e.getMessage());
}
}
}

# 2.2 客户端代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

public class Client {
private static final String SERVER_ADDRESS = "localhost";
private static final int PORT = 12345;

public static void main(String[] args) {
try (Socket socket = new Socket(SERVER_ADDRESS, PORT);
PrintWriter out = new PrintWriter(socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(new InputStreamReader(socket.getInputStream()));
BufferedReader stdIn = new BufferedReader(new InputStreamReader(System.in))) {

System.out.println("Connected to server");

String userInput;
while ((userInput = stdIn.readLine()) != null) {
out.println(userInput);
String response = in.readLine();
System.out.println("Server response: " + response);
}
} catch (IOException e) {
System.err.println("Error connecting to server: " + e.getMessage());
}
}
}

# 3. 代码解释

# 3.1 服务器端

  • ServerSocket 类用于创建一个服务器套接字,监听指定的端口(这里是 12345)。
  • serverSocket.accept() 方法会阻塞,直到有客户端连接到服务器。一旦有客户端连接,它会返回一个 Socket 对象,用于与客户端进行通信。
  • BufferedReader 用于从客户端读取消息, PrintWriter 用于向客户端发送消息。
  • 服务器使用一个无限循环来持续监听客户端连接,并处理客户端发送的消息。

# 3.2 客户端

  • Socket 类用于创建一个客户端套接字,连接到指定的服务器地址(这里是 localhost )和端口(12345)。
  • BufferedReader 用于从控制台读取用户输入的消息, PrintWriter 用于将消息发送给服务器。
  • 客户端使用一个循环来持续读取用户输入,并将输入的消息发送给服务器,同时接收服务器的响应并打印出来。

# 4. 运行步骤

  1. 首先,运行 Server 类,启动服务器。你会看到控制台输出 Server is listening on port 12345
  2. 然后,运行 Client 类,启动客户端。你会看到控制台输出 Connected to server
  3. 在客户端的控制台输入一些消息,按回车键发送。你会看到服务器接收并返回消息,客户端控制台会显示服务器的响应。

# 5. 注意事项

  • 确保服务器和客户端在同一网络中,或者使用正确的服务器地址。
  • 当服务器或客户端关闭时,要确保正确关闭所有的 SocketBufferedReaderPrintWriter 对象,以避免资源泄漏。