设计C/S架构的IM通信软件(2)

在之前基础上实现的功能:

1.自定义客户端,让服务器实现多客户端连接

2.服务器广播消息

客户类:

复制代码
public class MClient {
    public static void main(String[] args) {
        try {
            new MClient().StartMClient();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //创建客户端 获取输入输出流 启动线程不实时 读取服务器发来的消息 还有去发送消息
    public OutputStream os;
    public InputStream is;
    public void StartMClient() throws IOException {
        Socket socket = new Socket("127.0.0.1",9999);
        os = socket.getOutputStream();
        is = socket.getInputStream();
        new Thread(new Runnable() {
            @Override
            public void run() {
                String msg = null;
                try {
                    msg = readMsg();
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                System.out.println("Server:"+msg);
            }
        }).start();
        //发送消息
        while(true){
            Scanner scan = new Scanner(System.in);//从键盘获得输入
            String line = scan.nextLine();//当输入回车时 把前面输入的字符保存到字符串
            sendMsg(line);
        }
    }
    //写sendmsg的方法
    public void sendMsg(String msg) throws IOException {
        String str = msg +"\r\n";
        os.write(str.getBytes());
        os.flush();
    }
    //写readmsg的方法
    public String readMsg() throws IOException {
        //保存消息的缓冲区
        byte[] b = new byte[1024];
        //输入流读
        is.read(b);
        //字节换成字符串
        String msg = new String(b);
        //去掉字符串左右的空白部分
        return msg.trim();
    }
}

服务器类:

复制代码
public class MServer {
    public static void main(String[] args) {
        try {
            new MServer().startMServer();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //创建服务器 用list存客户端 while循环去连接客户端 添加到lists 启动线程保持通信状态
    public void startMServer() throws IOException {
        //创建服务器
        ServerSocket server = new ServerSocket(9999);
        System.out.println("启动服务器....");
        //用来存放socket客户端的list
        ArrayList<Socket> lists = new ArrayList<>();
        while(true){
            //阻塞监听器连接过来的客户端
            Socket socket = server.accept();
            lists.add(socket);
            //启动线程保持通信状态
            ServerThread serverThread = new ServerThread(socket,lists);
            new Thread(serverThread).start();
        }
    }
}

服务器线程类:

复制代码
public class ServerThread implements Runnable{
    //构筑方法先把必要的客户端和lists传入 包括重新得到is os输入输出流
    public Socket socket;
    public InputStream is;
    public OutputStream os;
    public ArrayList<Socket> lists;
    public ServerThread(Socket socket, ArrayList<Socket> lists){
        this.socket = socket;
        this.lists = lists;
        try {
            is = socket.getInputStream();
            os = socket.getOutputStream();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //用while循环 读取到的msg消息 并把客户端的消息广播给所有在线的人 不发自己
    public void run() {
        try {
            String msg = readMsg();
            for(Socket s:lists){
                if(s != socket){//不发给自己
                    OutputStream output = s.getOutputStream();
                    sendMsg(output,msg);
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    //发送消息 sendMsg
    public void sendMsg(OutputStream os, String msg) throws IOException {
        String str = msg + "\r\n";
        os.write(str.getBytes());
        os.flush();
    }
    //读取消息 readMsg
    public String readMsg() throws IOException {
        byte[] b = new byte[1024];
        is.read(b);
        String msg = new String(b);
        return msg.trim();
    }
}
相关推荐
wasp5206 分钟前
Vibe-Trading 深度解析(一):用 LLM 驱动的完整股票研究智能体架构总览
人工智能·架构·交易·ai coding·vibe trading
@灯神9 分钟前
SpringAI系列|第1篇:SpringAI概述与快速上手
java·人工智能·spring·ai·ai编程
国科安芯26 分钟前
抗辐射微控制器在卫星电源管理分系统中的控制架构与可靠性研究——基于AS32S601型MCU的星载能源系统智能化管理技术分析
网络·单片机·嵌入式硬件·安全·架构·系统架构·能源
中国搜索直付通28 分钟前
避开直付通选型暗礁:二级商户的合规生存与背景甄别
java·大数据·开发语言·人工智能·游戏
微三云云仔32 分钟前
GEO系统技术架构拆解:微三云双引擎产品的模块化设计逻辑
架构
不才不才不不才1 小时前
Spring AI 实战(7):向量库怎么选?PgVector/Redis/Milvus 横向对比
java·人工智能·spring·ai
Qimooidea1 小时前
祁木 CAD Translator 深度评测:从参数解析到工程交付实战
java·开发语言·人工智能·机器翻译
我登哥MVP2 小时前
走进 Gang of Four 设计模式:解释器模式
java·设计模式·解释器模式
智码看视界2 小时前
Tomcat架构深度拆解:Connector和Container到底怎么配合的?
java·servlet·架构·tomcat·web服务器