设计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();
    }
}
相关推荐
疯狂打码的少年5 小时前
【数据库技术】关系模型基本概念(关系/属性/元组/键)
java·服务器·数据库·笔记
Mr数据杨6 小时前
【Codex】用学生入学评估模块建立新生能力画像
android·java·javascript·django·codex·项目开发
2601_962056237 小时前
Spring Boot 入门 与 无法解析符号 springframework 的解决
java·spring boot·后端
luj_17687 小时前
大律师考核应重能力与科技素养
c语言·开发语言·c++·经验分享·算法
Mr数据杨7 小时前
【Codex】用部门管理模块维护组织架构与管理层级
架构·django·codex·项目开发
Thomas21437 小时前
Java scala 数组 链表
java·链表·scala
刃神太酷啦7 小时前
Linux 系统 MySQL 完整安装配置教程:从卸载 MariaDB 到优化 my.cnf----《Hello MySQL!》(1)
android·linux·c语言·c++·mysql·leetcode·mariadb
亚历克斯神7 小时前
低代码与 AI 的融合趋势——从可视化搭建到自然语言生成应用
java·spring·微服务
Capricorn19887 小时前
个人知识库接入大模型频现“幻觉引用”?排查 RAG 溯源失效问题,解析知芽构建可信第三大脑的底层架构
大数据·论文阅读·人工智能·笔记·架构·论文笔记
学长毕业设计8 小时前
基于SpringBoot的瑜伽馆网站的设计与实现(源码+文档+讲解视频)
java·spring boot·后端