Socket 编程的demo(多线程版本)

前言

网络编程的过程,类似于使用 QQ 的一个点对群的聊天。
一个服务端,多个客户端,客户端发送信息到服务端,当发送的是 exit 时,就关闭当前连接,关闭的方式是使得线程运行结束。

项目

其实就是2个类。
一个是服务端,如果您有兴趣,可以将这个线程池的方式更改为 ThreadPoolExecutor 这个类。

服务端代码

package thread.v1;

import javax.net.ServerSocketFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 服务端
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocketFactory serverSocketFactory = ServerSocketFactory.getDefault();
        // 构建服务端 Socket 并设置端口
        ServerSocket serverSocket = serverSocketFactory.createServerSocket(9999);

        // 创建一个线程池
        ExecutorService executorService = Executors.newFixedThreadPool(100);
        while(true){
            // 客户端连接
            Socket socket = serverSocket.accept();
            executorService.submit(() -> {
                try {
                    // 客户端输入
                    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    String line;
                    while ((line = reader.readLine()) != null){
                        // 读一行数据打印
                        System.out.println("客户端来信:" + line);
                        if("exit".equals(line)){
                            System.err.println("客户端 " + socket.getInetAddress().getHostAddress() + "正在退出连接!");
                            break;
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

客户端代码

package thread.v1;

import java.io.*;
import java.net.Socket;
import java.nio.charset.StandardCharsets;

public class Client {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 9999);

        // socket 获取字符流
        BufferedWriter bufferedWriter = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
        BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
        //通过标准输入流获取字符流
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in, StandardCharsets.UTF_8));

        String line;
        while((line = bufferedReader.readLine()) != null){
            bufferedWriter.write(line);
            bufferedWriter.newLine();
            bufferedWriter.flush();
        }
    }
}

优化过的服务端

package thread.v1;

import javax.net.ServerSocketFactory;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.concurrent.*;

/**
 * 服务端
 */
public class Server {
    public static void main(String[] args) throws IOException {
        ServerSocketFactory serverSocketFactory = ServerSocketFactory.getDefault();
        // 构建服务端 Socket 并设置端口
        ServerSocket serverSocket = serverSocketFactory.createServerSocket(9999);

        // 创建一个线程池
        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(60,
                100,
                20,
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(20),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );

        while(true){
            // 客户端连接
            Socket socket = serverSocket.accept();
            threadPoolExecutor.submit(() -> {
                try {
                    // 客户端输入
                    BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                    String line;
                    while ((line = reader.readLine()) != null){
                        // 读一行数据打印
                        System.out.println("客户端来信:" + line);
                        if("exit".equals(line)){
                            System.err.println("客户端 " + socket.getInetAddress().getHostAddress() + "正在退出连接!");
                            break;
                        }
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                } finally {
                    try {
                        socket.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }
}

结果和总结

在这里插入图片描述

发布了159 篇原创文章 · 获赞 129 · 访问量 4万+
展开阅读全文

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 终极编程指南 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览