基于Java Socket的多人在线聊天

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_29451823/article/details/78741801

上一篇: Java Socket 基于UDP协议的多线程连接

  1. 思路:
    • 所有人都访问一个地址和端口号
    • 用户接受消息都单独放在一个开启了线程的类里面
    • 在主方法Client里面调用这两个线程类
    • 服务器用一个List集合来保存连接的用户Socket连接,并且用一个不终止
    • 的循环不断开启线程来接受和发送Socket消息,接受一个Socket
    • 连接后,将Socket保存在List集合中,并且将消息发送给非当前发送消
    • 息用户的用户Socket。这样简单的实现类多人Socket聊天,相当于一
    • QQ讨论组一样的形式.
  2. 项目结构
    这里写图片描述

  3. ThreadWriter.java源码

    package cjj.online.cn;
    import java.io.IOException;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.util.Scanner;
    
    /**
    *@author:蔡佳君
    *@date:2017年12月7日 上午10:57:34
    *@version:
    *@description:用户输入,保存到socket中去
    */
    public class ThreadWriter extends Thread{
        Socket socket;
        public ThreadWriter(Socket socket) {
            this.socket = socket;
        }
    
        public void run() {
            try {
                Scanner sc = new Scanner(System.in);
                int i = 0;
                while(true) {
                    System.out.println("第的" + i++ + "条消息:");
                    String str = sc.next();
                    OutputStream os = socket.getOutputStream();
                    //将输入的字符写入到利用输出流写到socket中保存
                    os.write(str.getBytes());
                } 
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }
    
  4. TheadReader.java源码

     package cjj.online.cn;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.util.ArrayList;
    
    /**
    *@author:蔡佳君
    *@date:2017年12月7日 上午11:04:50
    *@version:
    *@description:
    */
    public class TheadReader extends Thread{
    
        Socket socket;
        public TheadReader(Socket socket) {
            this.socket = socket;
        }
        @Override
        public void run() {
            try {
                while(true) {
                        //利用输出流得到socket中的消息.
                        InputStream is = socket.getInputStream();
                        byte[] b = new byte[1024];
                        //读取到字节b中,并获取字节的个数。
                        int len = is.read(b);
                        //转化为字符
                        String str = new String(b,0,len);
                        System.out.println(str);   
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
            super.run();
        }
    }
    
  5. ServerThread.java源码

    package cjj.online.cn;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.util.ArrayList;
    
    /**
    *@author:蔡佳君
    *@date:2017年12月7日 上午10:31:09
    *@version:
    *@description:有多个客户端时,就会开启多个socket连接,
    *得到发送socket消息的socket。发送给其他未发送socket消息的
    *客户端
    */
    public class ServerThread extends Thread{
    
        Socket socket;
        ArrayList<Socket> list;
        InputStream is;
        OutputStream os;
        public ServerThread(Socket socket,ArrayList<Socket> list) {
            this.socket = socket;
            this.list = list;
        }
        @Override
        public void run() {
            try {
                while(true) {
                    //得到一个客户端的消息
                    is = socket.getInputStream();
                    byte[] b = new byte[1024];
                    int len = is.read(b);
                    String str = new String(b,0,len);
                    System.out.println(str);
                    for(Socket socket:list) {
                        //避免socket消息自己发给自己
                        if(this.socket != socket) {
                            os = socket.getOutputStream();
                            //输出流 写到socket中去
                            os.write(str.getBytes());
                        }
                    }
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
        }
    
  6. Client.java, Server.java源码

    package cjj.online.cn;
    import java.io.IOException;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    /**
    *@author:蔡佳君
    *@date:2017年12月7日 上午10:56:37
    *@version:
    *@description:
    */
    public class Client {
    
        public static void main(String[] args) throws Exception {
            Socket socket = new Socket("127.0.0.1",8888);
            new ThreadWriter(socket).start();
            new TheadReader(socket).start();
        }
    
    }
    -------------------------------------------------------------
    package cjj.online.cn;
    import java.io.IOException;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.ArrayList;
    
    /**
    *@author:蔡佳君
    *@date:2017年12月7日 上午10:27:43
    *@version:
    *@description:
    */
    public class Server {
        private static ArrayList<Socket> list = new ArrayList<Socket>();
        public static void main(String[] args) throws IOException {
            @SuppressWarnings("resource")
            ServerSocket server = new ServerSocket(8888);
            while(true) {
                //如果队列中没有等待的连接,套接字也没有被标记为Non-blocking,accept()会阻塞调用函数直到连接出现
                Socket socket = server.accept();
                //将连接的socket放到一个list集合
                list.add(socket);
                new ServerThread(socket,list).start();
            }
        }
    
    }
    

猜你喜欢

转载自blog.csdn.net/qq_29451823/article/details/78741801