Java TCP Server 多线程处理多客户端通信

407 阅读2分钟

在上篇中,我们学习了 TCP Socket Server/Client 的简单读写,有了这些基础后,结合 Java 多线程编程,我们就可以轻松实现 Java 多线程处理客户端的通信,这里仅在上篇的分享中,做了小小的改动,加入多线程的处理,一起来看看具体实现吧。

Server

package org.example;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;

/**
 * 单个server通过多线程处理多个客户端请求
 */
public class MultiThreadsSocketServer {
    public static void main(String[] args) throws IOException {
        System.out.println("------server------");
        // 1.绑定端口,创建服务器
        ServerSocket ss = new ServerSocket(8000);
        boolean isRunning = true;
        // 每新来一个客户端连接,创建新的线程处理请求
        while (isRunning) {
            // 2.等待客户端的连接
            Socket so = ss.accept();
            // 3.创建新的线程处理客户端请求
            new Thread(new Channel(so)).start();
        }

    }

    // 类内实现多线程接口
    static class Channel implements Runnable {
        private Socket so;
        // input stream
        private DataInputStream dis = null;
        // output stream
        private DataOutputStream dos = null;

        // init
        public Channel(Socket so) {
            this.so = so;
            try {
                dis = new DataInputStream(so.getInputStream());
                dos = new DataOutputStream(so.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
                close();
            }
        }

        // recv
        private String receive() {
            String content = "";
            try {
                content = dis.readUTF();
            } catch (IOException e) {
                e.printStackTrace();
            }

            return content;
        }

        // send
        private void send(String msg) {
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        // close
        private void close() {
            // dos -> dis -> so
            try {
                if (dos != null) {
                    dos.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                if (dis != null) {
                    dis.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            try {
                if (so != null) {
                    so.close();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }

            System.out.println(this.so.getRemoteSocketAddress().toString() + "'s resources have been released.");
        }

        // run, override
        @Override
        public void run() {
            System.out.println("New a client conn...");

            String username = "";
            String pwd = "";
            String[] datas = receive().split("&");

            for (String info: datas) {
                String[] userInfo = info.split("=");
                if (userInfo[0].equals("username")) {
                    username = userInfo[1];
                    System.out.println("您的用户名:" + username);
                } else if (userInfo[0].equals("pwd")) {
                    pwd = userInfo[1];
                    System.out.println("您的密码:" + pwd);
                }
            }

            if (username.equals("abc") && pwd.equals("123456")) {
                System.out.println("账号:" + username + ",登陆成功,欢迎回来。");
                send("账号:" + username + ",登陆成功,欢迎回来。");
            }else {
                System.out.println("账号:" + username + ",登陆失败,请检测账号密码。");
                send("账号:" + username + ",登陆失败,请检测账号密码。");
            }

            // release resources
            close();
        }
    }
}

Client

package org.example;

import java.io.*;
import java.net.Socket;

public class MultiThreadsSocketClient {
    public static void main(String[] args) throws Exception {
        System.out.println("------client------");

        // 1.建立连接
        Socket client = new Socket("localhost", 8000);
        // 2.IO操作
        new Send(client).send();
        new Recv(client).receive();

        // 3.释放资源
        client.close();
    }

    // send
    static class Send {
        private Socket client;

        private DataOutputStream dos;

        private BufferedReader br;

        private String msg;

        public Send(Socket client) {
            br = new BufferedReader(new InputStreamReader(System.in));
            this.msg = init();
            this.client = client;

            try {
                dos = new DataOutputStream(client.getOutputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        private String init() {
            try {
                System.out.println("请输入用户名:");
                String username= br.readLine();
                System.out.println("请输入密码:");
                String pwd = br.readLine();

                return "username=" + username + "&pwd=" + pwd;
            } catch (IOException e) {
                e.printStackTrace();
            }

            return null;
        }

        public void send() {
            try {
                dos.writeUTF(msg);
                dos.flush();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    // recv
    static class Recv {
        private Socket client;
        private DataInputStream dis;

        public Recv(Socket client) {
            this.client = client;

            try {
                dis = new DataInputStream(client.getInputStream());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        public void receive() {
            String msg = null;

            try {
                msg = dis.readUTF();
                System.out.println(msg);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
}

参考: