广告
返回顶部
首页 > 资讯 > 后端开发 > Python >Java Socket模拟实现聊天室
  • 214
分享到

Java Socket模拟实现聊天室

2024-04-02 19:04:59 214人浏览 八月长安

Python 官方文档:入门教程 => 点击学习

摘要

使用Java Socket模拟实现了一个聊天室,实现了基本的私聊以及群聊。分为服务器端和客户端,下面我来介绍一下实现的步骤。 服务器端 服务器端是聊天室的核心所在,主要用来处理客户端

使用Java Socket模拟实现了一个聊天室,实现了基本的私聊以及群聊。分为服务器端和客户端,下面我来介绍一下实现的步骤。

服务器端

服务器端是聊天室的核心所在,主要用来处理客户端的请求,先来看一下服务器端的主方法:


public static void main(String[] args) {
        try {
            ExecutorService executorService = Executors.newFixedThreadPool(100);//最多容纳100个客户端聊天
            ServerSocket serverSocket = new ServerSocket(6655);//监听6655号端口
            for (int i = 0; i < 100; i++) {
                Socket client = serverSocket.accept();
                System.out.println("有新的用户连接 " + client.getInetAddress() +
                        client.getPort());
                executorService.execute(new ExecuteClientThread(client));
            }
            executorService.shutdown();
            serverSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

首先我创建了一个固定大小为100的线程池,这个聊天室的实现是一个服务器线程对应一个客户端线程的,就是说线程池的大小就是最大的同时聊天的人数。服务器的执行顺序是这样的:

1.监听端口,等待客户端连接

2.如果有客户端连接到监听的端口,那么通过accept()方法返回该客户端的Socket,并且在线程池中启动一个新的服务器线程用来与刚刚连接的客户端"沟通"。

3.把接收到的客户端的Socket构造注入新启动的服务器线程中,这样服务器线程就可以获取到客户端对应的流。

到这里,服务器已经和客户端连接成功了,我们现在来看一下服务器线程是如何处理客户端的请求的,先上一段服务器代码


private static Map<String, Socket> clientMap = new ConcurrentHashMap<>();//存储所有的用户信息
 
    static class ExecuteClientThread implements Runnable {
        private Socket client;//每一个服务器线程对应一个客户端线程
        ExecuteClientThread(Socket client) {
            this.client = client;
        }
......

代码的第一行,创建了一个ConcurrentHashmap,这个map不是某个线程中的,而是服务器的static属性,用来存储所有客户端的信息。因为客户端是有姓名,有Socket的,所以采用K-value的模式来存储,用户名作为Key。考虑到线程安全的原因,采用了ConcurrentHashmap,保证了线程安全。

接下来就是刚刚构造注入的、连接的客户端的Socket了,我们可以通过这个Socket获取到输入和输出流。

然后就是服务器的线程执行的run方法了,具体的就直接看代码把。都有注释,就不一一解释了,以下是所有服务器端的代码


import java.io.IOException;
import java.io.PrintStream;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
 
 
 
public class Main {
 
 
    private static Map<String, Socket> clientMap = new ConcurrentHashMap<>();//存储所有的用户信息
 
    static class ExecuteClientThread implements Runnable {
        private Socket client;//每一个服务器线程对应一个客户端线程
        ExecuteClientThread(Socket client) {
            this.client = client;
        }
 
        @Override
        public void run() {
            boolean Flag = true;//防止一个客户端多次注册所做的标记位置
            try {
                PrintStream PrintToCilent = new PrintStream(client.getOutputStream());//服务器向用户输出一些提示信息
 
 
                Scanner scanner = new Scanner(client.getInputStream());
                String str = null;//用户外部的输入信息
                while (true) {
                    if (scanner.hasNext()) {
                        str = scanner.next();//外部的用户输出
 
                        Pattern pattern = Pattern.compile("\r");//排除特殊符号
                        Matcher matcher = pattern.matcher(str);
                        str = matcher.replaceAll("");
 
                        if (str.startsWith("userName")) {
                            String userName = str.split(":")[1];
                            userReGISt(userName, client, Flag);
                            Flag = false;
                        }
                        // 群聊流程
                        else if (str.startsWith("G:")) {
                            PrintToCilent.println("已进入群聊模式!");
                            groupChat(scanner,client);
                        }
                        // 私聊流程
                        else if (str.startsWith("P")) {//模式
                            String userName = str.split("-")[1];
                            PrintToCilent.println("已经进入与"+userName+"的私聊");
 
                            privateChat(scanner,userName);
                        }
                        // 用户退出
                        else if (str.contains("byebye")) {
                            String userName = null;
                            for (String geTKEy:clientMap.keySet()) {
                                if (clientMap.get(getKey).equals(client)) {
                                    userName = getKey;
                                }
                            }
 
                            System.out.println("用户"+userName+"下线了..");
                            clientMap.remove(userName);//将此实例从map中移除
                        }
                    }
                }
 
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
       
        private void userRegist(String userName, Socket client, boolean Flag) throws IOException {
            PrintStream PrintToCilent = new PrintStream(client.getOutputStream());//服务器向用户输出一些提示信息
            if(Flag) {
                System.out.println("用户" + userName + "上线了!");
 
                clientMap.put(userName, client);//把用户加入储存map
                System.out.println("当前群聊人数为" + (clientMap.size()) + "人");
                PrintToCilent.println("注册成功!");
            }else {
                PrintToCilent.println("警告:一个客户端只能注册一个用户!");
            }
        }
     
        private void groupChat(Scanner scanner,Socket client) throws IOException {
            // 取出clientMap中所有客户端Socket,然后遍历一遍
            // 分别取得每个Socket的输出流向每个客户端输出
            PrintStream PrintToClient = new PrintStream(client.getOutputStream());//在群聊的时候服务器向客户端发送数据
            boolean ExitFlag = false;
 
            Set<Map.Entry<String, Socket>> entrySet =
                    clientMap.entrySet();
 
            String userName = null;
            for (Map.Entry<String, Socket> socketEntry : entrySet) {//获得:是哪个用户说的话
                if (socketEntry.getValue() == client) {
                    userName = socketEntry.getKey();//发出信息的用户
                }
            }
            String msg = null;
 
            while (true) {
                if (scanner.hasNext()) {
                    msg = scanner.next();
                    if("exit".equals(msg)){//如果用户退出了
                        for(Map.Entry<String,Socket> stringSocketEntry : entrySet){
                            new PrintStream(stringSocketEntry.getValue().getOutputStream(),true).println("用户"+userName+"刚刚退出了群聊!!");//给所有人发退出群聊的消息
                        }
                        return;
                    }
 
 
                    for (Map.Entry<String, Socket> stringSocketEntry : entrySet) {//遍历用户的map,获取所有用户的Socket
                        try {
                            Socket socket = stringSocketEntry.getValue();
                            PrintStream ps = new PrintStream(socket.getOutputStream(), true);
 
                            ps.println("群聊:用户" + userName + "说: " + msg);//给每个用户发消息
                        } catch (IOException e) {
                            e.printStackTrace();
                        }
                    }
 
                }
            }
 
        }
        private void privateChat(Scanner scanner, String privatepeopleName) throws IOException {
 
            Socket privateUser = clientMap.get(privatepeopleName);
            PrintStream ps = new PrintStream(privateUser.getOutputStream());//拿到私聊对象的输出流
            PrintStream PrintToClient = new PrintStream(client.getOutputStream());//拿到当前客户端的输出流
            String Message = null;
            String MyName = null;
            Set<Map.Entry<String,Socket>> set = clientMap.entrySet();
            for(Map.Entry<String,Socket> value : set){
                if(value.getValue() == client){
                    MyName = value.getKey();
                    break;
                }
            }
 
            while (true) {
                if(scanner.hasNext()) {
                    Message = scanner.next();
                    if ("exit".equals(Message)){//如果用户输入了退出
                        PrintToClient.println("已退出和"+privatepeopleName+"的私聊");
                        ps.println("对方已经退出了私聊");
                        break;
                    }
                    ps.println(MyName+"说"+Message);//如果用户没有退出,向私聊对象发送消息
                }
            }
 
 
        }
 
 
    }
 
    public static void main(String[] args) {
        try {
            ExecutorService executorService = Executors.newFixedThreadPool(100);//最多容纳100个客户端聊天
            ServerSocket serverSocket = new ServerSocket(6655);
            for (int i = 0; i < 100; i++) {
                Socket client = serverSocket.accept();
                System.out.println("有新的用户连接 " + client.getInetAddress() +
                        client.getPort());
                executorService.execute(new ExecuteClientThread(client));
            }
            executorService.shutdown();
            serverSocket.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

然后是客户端的代码,客户端的代码比较简单:分为两个线程,一个线程用于接收服务器的数据,一个线程用于向服务器发送数据。我就直接上代码了,里面有注释的。


import java.io.IOException;
import java.io.PrintStream;
import java.net.Socket;
import java.util.Scanner;
 
 
class ExcuteServerInPut implements Runnable{//接收服务器的数据
    private Socket ToServer;
 
    ExcuteServerInPut(Socket ToServer){
        this.ToServer = ToServer;
    }
 
    @Override
    public void run() {
        try {
            Scanner scanner = new Scanner(ToServer.getInputStream());
               while (scanner.hasNext()){
                System.out.println(scanner.nextLine());
            }
            scanner.close();
            ToServer.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
class ExcuteServerOutPut implements Runnable{//向服务器发送数据
 
    private Socket Socket;
    ExcuteServerOutPut(Socket Socket){
        this.Socket = Socket;
    }
 
    @Override
    public void run() {
        try {
            PrintStream printStream = new PrintStream(Socket.getOutputStream());
            Scanner scanner = new Scanner(System.in);
            scanner.useDelimiter("\n");
            System.out.println("*****************************************");
            System.out.println("***用户注册:useerName:同户名(仅限一次)***");
            System.out.println("***进入群聊:G:           退出群聊:exit***");
            System.out.println("***私聊:P-用户名         退出私聊:exit***");
            System.out.println("***********退出聊天室:byebye*************");
            while (true){
                if(scanner.hasNext()) {
                    String string = scanner.next();
                    printStream.println(string);
                    if ("byebye".equals(string)) {
                        System.out.println("退出!");
                        printStream.close();
                        scanner.close();
                        break;
                    }
                }
 
            }
 
            Socket.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
 
 
public class Main {
    public static void main(String[] args) throws IOException {
        Socket socket = new Socket("127.0.0.1", 6655);
        ExcuteServerInPut excuteServerInPut = new ExcuteServerInPut(socket);
        ExcuteServerOutPut excuteServerOutPut = new ExcuteServerOutPut(socket);
        new Thread(excuteServerInPut).start();
        new Thread(excuteServerOutPut).start();
        }
}

后续我会做一些改进,希望可以对大家有所帮助

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持编程网。

--结束END--

本文标题: Java Socket模拟实现聊天室

本文链接: https://www.lsjlt.com/news/129858.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • Java Socket模拟实现聊天室
    使用Java Socket模拟实现了一个聊天室,实现了基本的私聊以及群聊。分为服务器端和客户端,下面我来介绍一下实现的步骤。 服务器端 服务器端是聊天室的核心所在,主要用来处理客户端...
    99+
    2022-11-12
  • Java Socket实现简易聊天室
    Java-Socket编程实现简易聊天室(TCP),供大家参考,具体内容如下 实现一个服务器接收多个客户端 测试: 首先启动服务器,然后启动三个客户端,输入三个不同的用户名,分别在聊...
    99+
    2022-11-11
  • Java Socket实现聊天室功能
    本文实例为大家分享了Java Socket实现聊天室的具体代码,供大家参考,具体内容如下 1 创建登录判断类UserLogin import java.util.HashSet; i...
    99+
    2022-11-13
  • python socket实现聊天室
    本文实例为大家分享了python socket实现聊天室的具体代码,供大家参考,具体内容如下 server端 import socket import json,struct from concurrent.fu...
    99+
    2022-06-02
    python socket 聊天室
  • 怎么使用Java socket通信模拟QQ实现多人聊天室
    这篇文章主要介绍“怎么使用Java socket通信模拟QQ实现多人聊天室”,在日常操作中,相信很多人在怎么使用Java socket通信模拟QQ实现多人聊天室问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法...
    99+
    2023-07-02
  • Java基于Socket实现多人聊天室
    本文实例为大家分享了Java基于Socket实现简易版多人聊天室的具体代码,供大家参考,具体内容如下 一、 聊天室需求 1、一个服务端,多个客户端;2、实现客户端和服务端的交互;3、...
    99+
    2022-11-13
  • Java Socket怎样实现简易聊天室
    这篇文章主要介绍了Java Socket怎样实现简易聊天室,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。Java-Socket编程实现简易聊天室(TCP),具体内容如下实现一...
    99+
    2023-06-14
  • android socket聊天室功能实现
    前提概要 笔者很久之前其实就已经学习过了socket,当然也是用socket做过了聊天室,但是觉得此知识点比较一般,并无特别难的技术点,于是也并未深究。 然而近期一个项目中对...
    99+
    2022-06-06
    socket Android
  • java+socket实现简易局域网聊天室
    本文实例为大家分享了java+socket实现简易局域网聊天室的具体代码,供大家参考,具体内容如下 服务器端 ServerFrame.java package com.eze.cha...
    99+
    2022-11-13
  • Java聊天室之实现获取Socket功能
    目录一、题目描述二、解题思路三、代码详解一、题目描述 题目实现:获取远程服务器和客户机的IP地址和端口号。 二、解题思路 创建一个服务器类:ServerSocketFrame,继承J...
    99+
    2022-11-13
    Java实现聊天室 Java聊天室 Java 获取Socket
  • Java通过Socket实现简单多人聊天室
    本文实例为大家分享了Java通过Socket实现多人聊天室的具体代码,供大家参考,具体内容如下 Socket可以实现网络上两个程序通过双向通道进行数据的交换,此外它是Java中网络T...
    99+
    2022-11-12
  • Java Socket实现聊天室附1500行源代码
    目录项目需求分析基础分析项目部分代码摘要Dao的链表存储实现ServerListenServerReceive再看一下客户端的ClientReceive项目问题选择框中出现的不是用户...
    99+
    2022-11-12
  • Java聊天室之实现接收和发送Socket
    目录一、题目描述二、解题思路三、代码详解一、题目描述 题目实现:网络通信,实现信息的发送和接收。 二、解题思路 创建一个服务器类:ServerSocketFrame,继承JFrame...
    99+
    2022-11-13
    Java 聊天室 Java 聊天室接收Socket Java 聊天室发送Socket
  • Java Socket通信之聊天室功能
    本文实例为大家分享了Java Socket聊天室功能的具体代码,供大家参考,具体内容如下Client.javaimport java.io.*; import java.net.*; import java.util.*; public ...
    99+
    2023-05-30
    java socket 聊天室
  • node+socket实现简易聊天室功能
    本文实例为大家分享了node+socket实现简易聊天室的具体代码,供大家参考,具体内容如下 服务端 const net = require('net') const serv...
    99+
    2022-11-12
  • unity使用socket实现聊天室功能
    本文实例为大家分享了unity使用socket实现聊天室的具体代码,供大家参考,具体内容如下 unity聊天室服务端实现 using System; using System.C...
    99+
    2022-11-11
  • PHP+Socket系列之实现websocket聊天室
    本篇文章给大家带来了关于php+socket的相关知识,其中主要介绍了怎么使用php原生socket实现一个简易的web聊天室?感兴趣的朋友下面一起来看一下,希望对大家有帮助。 php原生s...
    99+
    2023-05-14
    php socket websocket
  • PHP+Socket之如何实现websocket聊天室
    这篇文章主要介绍了PHP+Socket之如何实现websocket聊天室的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇PHP+Socket之如何实现websocket聊天室文章都会有所收获,下面我们一起来看看吧...
    99+
    2023-07-05
  • Java聊天室之实现使用Socket传递音频
    目录一、题目描述二、解题思路三、代码详解多学一个知识点一、题目描述 题目实现:使用网络编程时,需要通过Socket传递音频文件。 二、解题思路 创建一个服务器类:ServerSock...
    99+
    2022-11-13
    Java实现聊天室 Java聊天室 Java Socket传递音频
  • Java Socket+多线程实现多人聊天室功能
    本文实例为大家分享了Java Socket+多线程实现多人聊天室的具体代码,供大家参考,具体内容如下 思路简介 分为客户端和服务器两个类,所有的客户端将聊的内容发送给服务器,服务器接...
    99+
    2022-11-12
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作