ServerSocket接受客户端连接

wen java案例 2

本文目录导读:

ServerSocket接受客户端连接

  1. 基本使用流程
  2. 核心方法详解
  3. 多线程处理客户端
  4. 使用线程池优化
  5. 完整的客户端-服务器示例
  6. 注意事项

在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();
        }
    }
}

注意事项

  1. 端口占用:确保端口没有被其他程序占用
  2. 异常处理:始终处理IOException
  3. 资源关闭:使用try-with-resources自动关闭资源
  4. 超时设置:为长时间不活动的连接设置超时
  5. 安全考虑:验证输入数据,防范恶意攻击

这个示例涵盖了ServerSocket的主要用法,从基础连接到多线程处理,你可以根据实际需求选择合适的实现方式。

抱歉,评论功能暂时关闭!