设计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();
    }
}
相关推荐
砚边数影2 小时前
逻辑回归实战(一):用户流失预测数据集设计,KingbaseES存储标签数据
java·人工智能·算法·机器学习·逻辑回归·线性回归·金仓数据库
天人合一peng2 小时前
unity获得和修改button的text(TMP)
java·前端·unity
枫叶丹42 小时前
【Qt开发】Qt系统(十)-> Qt HTTP Client
c语言·开发语言·网络·c++·qt·http
范纹杉想快点毕业2 小时前
自学嵌入式系统架构设计:有限状态机入门完全指南,C语言,嵌入式,单片机,微控制器,CPU,微机原理,计算机组成原理
c语言·开发语言·单片机·算法·microsoft
leiming62 小时前
c语言更进一步
c语言·开发语言
九皇叔叔2 小时前
【07】SpringBoot3 MybatisPlus 删除(Mapper)
java·开发语言·mybatis·mybatis plus
sheji34162 小时前
【开题答辩全过程】以 基于Spring Boot的化妆品销售系统的设计与实现为例,包含答辩的问题和答案
java·spring boot·后端
2501_941982055 小时前
企微中台架构:非官方接口与企业私有化 CRM 的深度集成
架构·企业微信
程途拾光1585 小时前
内存计算突破:打破传统架构的性能瓶颈
架构