飞道的博客

Java实现多人聊天室

354人阅读  评论(0)

多人聊天室原理图

源码

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

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();
    }
}

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


有喜欢的小伙伴可以自己拿去玩,代码复制直接有效。


转载:https://blog.csdn.net/weixin_44991304/article/details/115347574
查看评论
* 以上用户言论只代表其个人观点,不代表本网站的观点或立场