设计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();
    }
}
相关推荐
橙淮1 小时前
并发编程(六)
java·jvm
千里马学框架1 小时前
aosp新增窗口层级 Type 完整实现方案(有源码)-wms需求和面试题
android·智能手机·架构·wms·aaos·车机
拽着尾巴的鱼儿1 小时前
springboot openfeign 自定义feign 接口重试机制
java·spring boot·后端
白露与泡影1 小时前
2026大厂Java面试题大全!牛客网最新版
java·开发语言
EntyIU2 小时前
JVM内存与GC笔记
java·jvm·笔记
AI_Auto2 小时前
【智能制造】- APS系列|14 生产计划三层架构:长期、中期、短期
架构·制造
XS0301062 小时前
并发编程 六
java·后端
yaoxin5211232 小时前
419. 现代 Java IO 最佳实践 - 写入文本文件
java·windows·python
雪宫街道2 小时前
synchronized 锁的范围:对象锁、类锁与代码块锁
java·jvm·后端·面试
morning_judger2 小时前
Agent系列(一) - Agent系统分层架构
人工智能·架构