Java实现多人聊天室

多人聊天室原理图

在这里插入图片描述

源码

工具类:
该类用于关闭各种流。

public class CloseUtil {
    
    
    public static void CloseAll(Closeable... closeable){
    
    
        for(Closeable c:closeable){
    
    
            if (c != null) {
    
    
                try {
    
    
                    c.close();
                } catch (IOException e) {
    
    
                    e.printStackTrace();
                }
            }
        }
    }
}

服务器:
服务器端创建一个serverSocket对象通过accept()方法监听是否有tcp连接,同时有一个储存socket对象的集合将连接进来的对象储存到List集合中,服务器将消息进行转发。

//服务器
public class Server {
    
    
    //存储每一个连接进来的客户端
    public static List<MyChannel> list=new ArrayList<>();

    public static void main(String[] args) throws Exception {
    
    
         //创建ServerSocket对象
        ServerSocket serverSocket = new ServerSocket(9999);
        while (true){
    
    
            //连接进来的客户端
            Socket client = serverSocket.accept();
            System.out.println(client.getInetAddress()+"进入聊天室");
        MyChannel myChannel = new MyChannel(client);
        list.add(myChannel);
        new Thread(myChannel).start();
        }
    }
}

消息转发类:
具体的消息转发实现类,将信息发给除发送消息以外的其他客户端。

//用于信息转发
public class MyChannel implements Runnable{
    
    
    private DataInputStream dis;
    private DataOutputStream dos;
    private boolean flag=true;

    public MyChannel(Socket socket) {
    
    
        try{
    
    
            dis=new DataInputStream(socket.getInputStream());
            dos=new DataOutputStream(socket.getOutputStream());
        }catch (IOException e){
    
    
            flag=false;
            CloseUtil.CloseAll(dis,dos);
        }
    }
    //接收数据的方法
    private String receive(){
    
    
        String str="";
        try{
    
    
            str= dis.readUTF();
        }catch (IOException e){
    
    
            flag=false;
            CloseUtil.CloseAll(dis,dos);
            Server.list.remove(this);
        }
        return str;
    }
    //发送数据的方法
    private void send(String str){
    
    
        try {
    
    
            if (str != null && str.length() != 0) {
    
    
                dos.writeUTF(str);
                dos.flush();
            }
        }catch (Exception exception){
    
    
           flag=false;
           CloseUtil.CloseAll(dos,dis);
           Server.list.remove(this);
        }
    }
    //转发消息的方法
    private void sendToOther(){
    
    
        String str=this.receive();
        List<MyChannel> list = Server.list;
        for (MyChannel other:list) {
    
    
            if(other==list){
    
    
                continue;//不发送信息给自己
            }
            //将消息发送给其他客户端
            other.send(str);
        }
    }

    @Override
    public void run() {
    
    
        while (flag){
    
    
            sendToOther();
        }
    }
}

发送信息类:
用于从键盘上获取数据然后将数据发送出去

public class Send implements Runnable{
    
    
    //从键盘上获取数据
    private BufferedReader br;
    private DataOutputStream dos;
    private boolean flag=true;

    public Send() {
    
    
        br=new BufferedReader(new InputStreamReader(System.in));
    }
    public Send(Socket socket){
    
    
        this();
        try{
    
    
            dos=new DataOutputStream(socket.getOutputStream());
        }catch (Exception e){
    
    
            flag=false;
            CloseUtil.CloseAll(dos,socket);
            e.printStackTrace();
        }
    }


    private String getMessage(){
    
    
        String str="";
        try{
    
    
            str=br.readLine();
        }catch (IOException e){
    
    
            flag=false;
            CloseUtil.CloseAll(br);
        }
        return str;
    }
    private void send(String str){
    
    
        try {
    
    
            dos.writeUTF(str);
            dos.flush();
        } catch (IOException e) {
    
    
            flag=false;
            CloseUtil.CloseAll(dos);
            e.printStackTrace();
        }

    }

    @Override
    public void run() {
    
    
        while (flag){
    
    
            this.send(getMessage());
        }
    }
}

信息接收类:

public class Receive implements Runnable{
    
    
    //接受数据流
    private DataInputStream dis;
    private boolean flag=true;


    public Receive(Socket socket){
    
    
        try {
    
    
            dis = new DataInputStream(socket.getInputStream());
        }catch (Exception e){
    
    
            flag=false;
            CloseUtil.CloseAll(dis,socket);
        }
    }
    private String getMessage(){
    
    
        String str="";
        try {
    
    
            str=dis.readUTF();
        } catch (IOException e) {
    
    
            flag=false;
            CloseUtil.CloseAll(dis);
            e.printStackTrace();
        }
        return str;
    }
    @Override
    public void run() {
    
    
        while (flag){
    
    
            System.out.println(this.getMessage());
        }
    }
}

客户端:

public class client {
    
    
    public static void main(String[] args) throws Exception{
    
    
        Socket socket = new Socket(InetAddress.getLocalHost(),9999);
        Send send = new Send(socket);
        Receive receive = new Receive(socket);
        new Thread(send).start();
        new Thread(receive).start();
    }
}

先将服务器启动然后启动客户端:测试结果如下

在这里插入图片描述
有喜欢的小伙伴可以自己拿去玩,代码复制直接有效。

猜你喜欢

转载自blog.csdn.net/weixin_44991304/article/details/115347574