Java聊天系统---《海内天涯0.9.2》(公测中级版)

版权声明:禁止侵权,打击盗版! https://blog.csdn.net/ChenGX1996/article/details/82420545

该聊天系统实现了Java多线程之间互相通信;

该程序中最多创建10个线程,可选择上线、群聊、私聊、下线等功能;

服务器端:

package talkingplus;

import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Scanner;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 多线程聊天室服务器端
 */
public class MultiThreadServer {
    //存储所有注册的客户端
    private static Map<String,Socket> clientMap = new ConcurrentHashMap<String, Socket>();
    //具体处理与每个客户端通信的内部类
    private static class ExecuteClient implements Runnable {
        private Socket client;
        public ExecuteClient(Socket client){
            this.client = client;
        }

        @Override
        public void run() {

            try {
                //获取客户端输入流
                Scanner in = new Scanner(client.getInputStream());
                String strFromClient;
                while(true){
                    if(in.hasNextLine()){
                        strFromClient = in.nextLine();
                        //windows下将默认换行中\r\n中的\r替换为空字符串
                        Pattern pattern = Pattern.compile("\r");
                        Matcher matcher = pattern.matcher(strFromClient);
                        strFromClient = matcher.replaceAll("");
                        //注册流程
                        if(strFromClient.startsWith("注册")){
                            String UserName = strFromClient.split("\\:")[1];
                            //注册方法
                            zhuCe(UserName,client);
                            continue;
                        }
                        if(strFromClient.startsWith("群聊")){
                            String msg = strFromClient.split("\\:")[1];
                            //群聊
                            groupChat(msg);
                            continue;
                        }
                        if(strFromClient.startsWith("私聊")){
                            //要进行通信的用户名
                            String userName = strFromClient.split("\\:")[1].split(":")[0];
                            //要发送的内容
                            String msg = strFromClient.split("\\:")[1].split(":")[1];
                            //私聊
                            privateChat(strFromClient,msg);
                            continue;
                        }
                        if(strFromClient.startsWith("bye")){
                            String userName = null;
                            //根据Socket找到UserName
                            for (String keyName : clientMap.keySet()) {
                                if(clientMap.get(keyName).equals(client)){
                                    userName = keyName;
                                }
                            }
                            System.out.println("用户"+userName+"下线!");
                            System.out.println("当前群聊人数为:"+(clientMap.size()-1)+"人");
                            clientMap.remove(userName);
                            continue;
                        }
                    }
                }
            } catch (IOException e) {
                System.out.println("服务器异常!"+e);            }
        }
    }
    //注册方法
    private static void zhuCe(String userName, Socket client){
        System.out.println("用户姓名为:"+userName);
        System.out.println("用户"+userName+"上线了");
        System.out.println("当前群聊人数为:"+(clientMap.size()+1)+"人");
        //将用户信息保存到map中
        clientMap.put(userName,client);
        try {
            PrintStream out = new PrintStream(client.getOutputStream(),true,"UTF-8");
            //告知用户 注册成功
            out.println("注册成功!");
            out.println("请尽情畅聊吧");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    //群聊流程
    private static void groupChat(String msg){
        //取出所有clientMap中所有Entry遍历发送群聊信息
        Set<Map.Entry<String,Socket>> clientSet = clientMap.entrySet();
        for(Map.Entry<String,Socket>entry : clientSet){
            Socket socket = entry.getValue();
            //取得每个客户的的输出流
            try {
                PrintStream out = new PrintStream(socket.getOutputStream(),true,"UTF-8");
                out.println("群聊信息为:"+msg);
            } catch (IOException e) {
                System.out.println("群聊异常:"+e);
            }
        }
    }
    //私聊流程
    private static void privateChat(String userName,String msg) {
        Socket socket = clientMap.get(userName);
        try {
            PrintStream out = new PrintStream(socket.getOutputStream(), true, "UTF-8");
            out.println("私聊信息为:" + msg);
        } catch (IOException e) {
            System.out.println("私聊异常:" + e);
        }

    }
    public static void main(String[] args) throws IOException {
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        ServerSocket serverSocket = new ServerSocket(3366);
        for(int i=0;i<10;i++){
            System.out.println("等待客户端连接...");
            Socket client = serverSocket.accept();
            System.out.println("有新的客户端连接,端口号为:"+client.getPort());
            executorService.submit(new ExecuteClient(client));
        }
        executorService.shutdown();
        serverSocket.close();
    }
}

客户端:

package talkingplus;

import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;

/**
 * 读取服务器信息线程
 */
class ReadFromServerThread implements Runnable {
    private Socket client;
    ReadFromServerThread(Socket client) {
        this.client = client;
    }
    @Override
    public void run() {

        try {
            Scanner in = new Scanner(client.getInputStream());
            while(true){
                if(in.hasNextLine()){
                    System.out.println("系统消息:"+in.nextLine());
                }
                //客户端退出
                if(client.isClosed()){
                    System.out.println("您已成功下线!欢迎您下次再来:)");
                    break;
                }
            }
            in.close();
        } catch (IOException e) {
            System.out.println("客户端读入信息失败!");        }
    }
}

/**
 * 给服务器发消息
 */
class WriteToServer implements Runnable {
    private  Socket client;
    public WriteToServer(Socket client){
        this.client = client;
    }

    @Override
    public void run() {
        try {
            //获取键盘输入
            Scanner in = new Scanner(System.in);
            //获取客户端输出流
            System.out.println("欢迎来到海内天涯聊天室☎☎☎" +
                    "\n注册请输入:注册\\:+用户名" +
                    "\n 群聊请输入:群聊\\:+消息" +
                    "\n 私聊请输入:私聊\\:+私聊对象:+消息" +
                    "\n下线请输入:包含bye的任意消息" );
            PrintStream out = new PrintStream(client.getOutputStream());
            while(true){
                System.out.println("请输入消息:");
                String string;
                if(in.hasNextLine()){
                    string = in.nextLine();
                    out.println(string);
                    //客户端退出标志
                    if(string.contains("bye")){
                        System.out.println("客户端退出");
                        in.close();
                        out.close();
                        client.close();
                        break;
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
/**
 * 多线程聊天室客户端
 */
public class MultiThreadClient {
    public static void main(String[] args){
        try {
            Socket client = new Socket("127.0.0.1",3366);
            //读取消息线程
            Thread readFromServer = new Thread(new ReadFromServerThread(client));
            //写入消息线程
            Thread writeToServer = new Thread(new WriteToServer(client));
            readFromServer.start();
            writeToServer.start();
        } catch (IOException e) {
            System.out.println("客户端异常:"+e);
        }
    }
}

运行服务器:

运行客户端:

运行若干客户端:

注册、发送消息;

欢迎加入《海内天涯》测试...

猜你喜欢

转载自blog.csdn.net/ChenGX1996/article/details/82420545