java:基于TCP协议的网络聊天室

基于TCP协议的网络聊天室

简单用java写了一个基于TCP协议的网络聊天室

基本功能

多用户同时在线聊天

收到消息时服务端会向所有在线用户群发消息

用户加入连接和断开连接时会提示

服务端

 Socket socket;
    ArrayList<Socket> list;

    public ServerThread(Socket socket, ArrayList<Socket> list) {
        this.socket = socket;
        this.list = list;
    }

    @Override
    public void run() {
        try {
            BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            InetAddress ip = socket.getInetAddress();
            int port = socket.getPort();
            System.out.printf("欢迎ip为%s,端口号为%d的用户进入聊天室\n", ip.getHostAddress(), port);
            while (true) {
                String s = br.readLine();
                System.out.println(s);
                System.out.println("开始广播");
                System.out.println(list);
                for (Socket socket1 : list) {
                    BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(socket1.getOutputStream()));
                    bw.write(s);
                    bw.newLine();
                    bw.flush();
                }
            }
        }catch (SocketException e){
            System.out.println("有人直接关闭了客户端");
        }catch (IOException e) {
            e.printStackTrace();
        }
    }

基于网络编程和io流实现对客户端消息的接收

收到消息时会对所有在线用户群发消息,即类似qq群效果

当用户直接关闭客户端时,由于违反了TCP的挥手协议,需要捕获不然会出现异常

客户端

客户端包含两个线程,一个用于接收服务端返回的群发数据,一个用于发送客户端发出的消息

 public static void main(String[] args) {
        try {
//            Socket socket = new Socket("127.0.0.1", 8000);
            Socket socket = new Socket("192.168.36.98", 8000);
            BufferedWriter bos = new BufferedWriter(new OutputStreamWriter(socket.getOutputStream()));
            new Thread(new Receive(socket)).start();
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入您的昵称");
            String nickname = sc.next();
            while (true) {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
                LocalDateTime ldt = LocalDateTime.now();
                String time = ldt.format(formatter);
                System.out.println(nickname + "要说些什么?");
                bos.write(time + " " + nickname + "说:" + sc.next());
                bos.newLine();
                bos.flush();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

基于网络编程和IO流实现消息的发送

基于java时间类描述消息

 Socket socket;

    public Receive(Socket socket) {
        this.socket = socket;
    }

    @Override
    public void run() {
        while (true) {
            try {
                BufferedReader br = new BufferedReader(new InputStreamReader(socket.getInputStream()));
                System.out.println(br.readLine());
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

接收服务端群发的消息并打印

主线程

static ArrayList<Socket> list = new ArrayList<>();
    public static void main(String[] args) throws IOException {
        ServerSocket server = new ServerSocket(8000);
        System.out.println("聊天室启动!!!");
        ThreadPoolExecutor tpe = new ThreadPoolExecutor(
                3,
                10,
                60,
                TimeUnit.SECONDS,
                new ArrayBlockingQueue<>(20),
                Executors.defaultThreadFactory(),
                new ThreadPoolExecutor.AbortPolicy()
        );
        while(true){
            Socket acp = server.accept();
            list.add(acp);
            tpe.submit(new Thread(new ServerThread(acp,list)));
        }
    }

主线程中创建了一个线程池并死循环接收新客户端的连接递交给线程池处理

实现演示

请添加图片描述

客户端发送消息,服务端接收并群发

请添加图片描述
请添加图片描述

多用户同时发送和接收消息

请添加图片描述
服务端对数据进行处理和收发

上一篇:Comparable 和 Comparator


下一篇:黑客技术(网络安全)自学2024