本文目录导读:

在Java中,ServerSocket是用于接受客户端连接的服务器端类,以下是详细介绍和使用示例:
基本使用流程
import java.io.*;
import java.net.*;
public class ServerExample {
public static void main(String[] args) {
try {
// 1. 创建ServerSocket,监听8080端口
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("服务器启动,等待客户端连接...");
// 2. 循环接受客户端连接
while (true) {
// 3. 接受客户端连接(阻塞方法)
Socket clientSocket = serverSocket.accept();
System.out.println("客户端连接成功:" +
clientSocket.getInetAddress().getHostAddress());
// 4. 处理客户端请求
handleClient(clientSocket);
}
} catch (IOException e) {
e.printStackTrace();
}
}
// 处理客户端的方法
private static void handleClient(Socket clientSocket) {
try {
// 获取输入输出流
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
// 读取客户端消息
String message = in.readLine();
System.out.println("收到客户端消息:" + message);
// 发送响应
out.println("服务器已收到消息:" + message);
// 关闭连接
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
核心方法详解
ServerSocket 构造方法
// 方法1:指定端口
ServerSocket serverSocket = new ServerSocket(8080);
// 方法2:指定端口和最大连接数
ServerSocket serverSocket = new ServerSocket(8080, 10);
// 方法3:指定端口、最大连接数和绑定地址
ServerSocket serverSocket = new ServerSocket(8080, 10,
InetAddress.getByName("127.0.0.1"));
// 方法4:默认端口
ServerSocket serverSocket = new ServerSocket(0); // 自动分配端口
常用方法
// 接受客户端连接(阻塞) Socket client = serverSocket.accept(); // 设置超时时间(毫秒) serverSocket.setSoTimeout(10000); // 10秒超时 // 获取服务器端口 int port = serverSocket.getLocalPort(); // 获取服务器地址 InetAddress address = serverSocket.getInetAddress(); // 关闭服务器 serverSocket.close(); // 检查是否绑定 boolean isBound = serverSocket.isBound(); // 检查是否关闭 boolean isClosed = serverSocket.isClosed();
多线程处理客户端
public class MultiThreadServer {
public static void main(String[] args) {
try {
ServerSocket serverSocket = new ServerSocket(8080);
System.out.println("多线程服务器启动...");
while (true) {
Socket clientSocket = serverSocket.accept();
// 为每个客户端创建新线程
new ClientHandler(clientSocket).start();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 客户端处理线程
class ClientHandler extends Thread {
private Socket clientSocket;
public ClientHandler(Socket socket) {
this.clientSocket = socket;
}
@Override
public void run() {
try {
System.out.println("处理客户端:" +
clientSocket.getInetAddress().getHostAddress());
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("收到:" + inputLine);
out.println("服务器响应:" + inputLine);
if ("bye".equalsIgnoreCase(inputLine)) {
break;
}
}
clientSocket.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用线程池优化
import java.util.concurrent.*;
public class ThreadPoolServer {
private static final int THREAD_POOL_SIZE = 10;
private static final int PORT = 8080;
public static void main(String[] args) {
ExecutorService executorService =
Executors.newFixedThreadPool(THREAD_POOL_SIZE);
try (ServerSocket serverSocket = new ServerSocket(PORT)) {
System.out.println("线程池服务器启动,端口:" + PORT);
while (true) {
Socket clientSocket = serverSocket.accept();
// 提交任务到线程池
executorService.submit(new ClientTask(clientSocket));
}
} catch (IOException e) {
e.printStackTrace();
} finally {
executorService.shutdown();
}
}
}
class ClientTask implements Runnable {
private Socket clientSocket;
public ClientTask(Socket socket) {
this.clientSocket = socket;
}
@Override
public void run() {
try {
System.out.println("处理客户端:" +
Thread.currentThread().getName() + " - " +
clientSocket.getInetAddress().getHostAddress());
// 处理逻辑...
Thread.sleep(1000); // 模拟处理时间
clientSocket.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
完整的客户端-服务器示例
服务器端
public class EchoServer {
public static void main(String[] args) {
try (ServerSocket serverSocket = new ServerSocket(8888)) {
System.out.println("Echo服务器运行在端口 8888...");
while (true) {
try (Socket clientSocket = serverSocket.accept()) {
System.out.println("新客户端连接");
BufferedReader in = new BufferedReader(
new InputStreamReader(clientSocket.getInputStream()));
PrintWriter out = new PrintWriter(
clientSocket.getOutputStream(), true);
String inputLine;
while ((inputLine = in.readLine()) != null) {
System.out.println("接收到: " + inputLine);
out.println("Echo: " + inputLine);
if ("quit".equalsIgnoreCase(inputLine)) {
System.out.println("客户端断开连接");
break;
}
}
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端
public class EchoClient {
public static void main(String[] args) {
try (Socket socket = new Socket("localhost", 8888);
BufferedReader userInput = new BufferedReader(
new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(
socket.getOutputStream(), true);
BufferedReader in = new BufferedReader(
new InputStreamReader(socket.getInputStream()))) {
System.out.println("连接到服务器,输入消息(输入quit退出)");
String userInputLine;
while ((userInputLine = userInput.readLine()) != null) {
out.println(userInputLine);
String response = in.readLine();
System.out.println("服务器响应: " + response);
if ("quit".equalsIgnoreCase(userInputLine)) {
break;
}
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
注意事项
- 端口占用:确保端口没有被其他程序占用
- 异常处理:始终处理IOException
- 资源关闭:使用try-with-resources自动关闭资源
- 超时设置:为长时间不活动的连接设置超时
- 安全考虑:验证输入数据,防范恶意攻击
这个示例涵盖了ServerSocket的主要用法,从基础连接到多线程处理,你可以根据实际需求选择合适的实现方式。