服务端多线程socket通信处理之线程池

GoogleVip8 1年前 ⋅ 462 阅读

一般都是用多线程的方式来处理Socket,即每有一个Socket请求的时候,就创建一个线程来处理它。

不过在实际生产中,创建的线程会交给线程池来处理,为了:

线程复用,创建线程耗时,回收线程慢。

防止短时间内高并发,指定线程池大小,超过数量将等待,方式短时间创建大量线程导致资源耗尽,服务挂掉。

int port = 55533;
int nThreads = 10;

ServerSocket serverSocket = new ServerSocket(port);
// demo 使用Executors创建线程池,正式是不推荐使用
ExecutorService executorService = Executors.newFixedThreadPool(nThreads);

// 循环获取socket通信
while (true) {
    Socket socket = serverSocket.accept();
    // 创建子线程处理socket通信
    executorService.submit(() -> {
        // 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
        try {
            // 建立好连接后,从socket中获取输入流,并建立缓冲区进行读取
            BufferedReader read = new BufferedReader(new InputStreamReader(socket.getInputStream(), "UTF-8"));
            String line;
            StringBuilder sb = new StringBuilder();
            while ((line = read.readLine()) != null) {
                //注意指定编码格式,发送方和接收方一定要统一,建议使用UTF-8
                sb.append(line);
            }
            System.out.println(sb);
            read.close();
            socket.close();

        } catch (IOException e) {
            e.printStackTrace();
        }
    });
}

对于同一个socket,如果关闭了输出流比如(pw.close()),则与该输出流关联的socket也会关闭,所以一般不需要关闭输出流,当关闭socket的时候,输出流也会关闭,直接关闭socket就行。

在使用TCP通信传输信息时,更多是使用对象的形式来传输,可以使用ObjectOutputStream对象序列化流来传递对象,比如ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());User user = new User("admin","123"); os.writeObject(user);

socket实现双向通信,发送消息并接受消息,地址:socket实现双向通信


全部评论: 0

    我有话说: