TCP案例-实时群聊

这篇具有很好参考价值的文章主要介绍了TCP案例-实时群聊。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现思路

  • 服务器端循环获取所有的客户端socket,放到一个socket的list中,等到需要通信的时候,调用相对应的管道就可以了
  • 客户端和服务器端一样,纪要发送消息,也要接受消息

代码

客户端

// tcp客户端
public class Client {
    public static void main(String[] args) throws IOException {
        // 1. 创建一个Socket对象
        // 参数一:服务端的ip地址
        // 参数二:服务端的端口号
        Socket socket = new Socket("127.0.0.1", 8888);

        // 创建一个独立的线程负责读取服务端发送过来的数据
        ClientReaderThread clientReaderThread = new ClientReaderThread(socket);
        clientReaderThread.start();

        // 2. 通过Socket对象获取一个输出流
        OutputStream outputStream = socket.getOutputStream();

        // 3. 把低级的字节输出流包装成高级的数据输出流
        // 这一步不是必须得,但是高级的数据输出流可以更方便的操作数据
        DataOutputStream dataOutputStream = new DataOutputStream(outputStream);

        Scanner scanner = new Scanner(System.in);
        while (true) {
            System.out.println("请输入要发送的数据:");
            String s = scanner.nextLine();

            // 4. 使用数据输出流向服务端发送数据
            dataOutputStream.writeUTF(s);
            dataOutputStream.flush();

            if (s.equals("exit")) {
                System.out.println("客户端退出");
                // 5. 关闭资源
                // dataOutputStream关闭的时候会自动关闭outputStream
                dataOutputStream.close();
                socket.close();
                Server.removeSocket(socket);
                break;
            }
        }
    }
}

客户端读取线程

读取线程是子线程文章来源地址https://www.toymoban.com/news/detail-860537.html

public class ClientReaderThread extends Thread {

    private Socket socket;

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

    @Override
    public void run() {

        try (
                // 1. 通过Socket对象获取一个输入流
                InputStream inputStream = socket.getInputStream();
                // 2. 将原始的字节输入流包装成高级的数据输入流
                // 这一步不是必须的,但是高级的数据输入流可以更方便的操作数据
                DataInputStream dataInputStream = new DataInputStream(inputStream);

        ) {
            while (true) {
                // 3. 读取客户端发送过来的数据
                String data = dataInputStream.readUTF();
                System.out.println("客户端发送过来的数据:" + data);
                System.out.println("客户端的ip地址:" + socket.getInetAddress().getHostAddress()
                        + ",客户端的端口号:" + socket.getPort());
                if (data.equals("exit")) {
                    System.out.println("客户端退出");
                    // 4. 关闭资源
                    socket.close();
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

服务端

// tcp服务端
public class Server {

    // 用来存储所有的socket对象
    private static ArrayList<Socket> onLineSockets = new ArrayList<Socket>();

    public static void main(String[] args) throws IOException {
        // 1. 创建服务端对象
        // 参数:服务端的端口号
        ServerSocket server = new ServerSocket(8888);


        while(true){
            // 2. 服务端一直处于监听状态,等待客户端的连接
            // accept()方法是一个阻塞方法,会一直等待客户端的连接
            Socket socket = server.accept();
            // 将socket对象存储到集合中
            onLineSockets.add(socket);

            // 3. 将socket独享交给独立的线程去负责
            ServerReaderThread serverReaderThread = new ServerReaderThread(socket);
            serverReaderThread.start();
        }
    }

    public static void removeSocket(Socket socket){
        onLineSockets.remove(socket);
    }

    public static ArrayList<Socket> getOnLineSockets(){
        return onLineSockets;
    }
}

服务段读取线程

public class ServerReaderThread extends Thread {

    private Socket socket;

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

    @Override
    public void run() {

        try (
                // 1. 通过Socket对象获取一个输入流
                InputStream inputStream = socket.getInputStream();
                // 2. 将原始的字节输入流包装成高级的数据输入流
                // 这一步不是必须的,但是高级的数据输入流可以更方便的操作数据
                DataInputStream dataInputStream = new DataInputStream(inputStream);

        ) {
            while (true) {
                // 3. 读取客户端发送过来的数据
                String data = dataInputStream.readUTF();
                // System.out.println("客户端发送过来的数据:" + data);
                // System.out.println("客户端的ip地址:" + socket.getInetAddress().getHostAddress()
                //         + ",客户端的端口号:" + socket.getPort());
                // 4. 将客户端发送过来的数据转发给所有的客户端
                sendMsgToAllClient(data);
                if (data.equals("exit")) {
                    System.out.println("客户端退出");
                    // 4. 关闭资源
                    socket.close();
                    break;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 异常抛出给上一级
    private void sendMsgToAllClient(String data) throws Exception{
        // 1. 获取所有的socket对象
        for (Socket socket : Server.getOnLineSockets()) {
            // 2. 通过socket对象获取一个输出流
            // 3. 将原始的字节输出流包装成高级的数据输出流
            // 这一步不是必须的,但是高级的数据输出流可以更方便的操作数据
            DataOutputStream dataOutputStream = new DataOutputStream(socket.getOutputStream());
            // 4. 使用数据输出流向客户端发送数据
            dataOutputStream.writeUTF(data);
            dataOutputStream.flush();
        }
    }
}

缺点

  • 只能实现群发,无法端到端
  • 也会发给自己

到了这里,关于TCP案例-实时群聊的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • python的WebSocket编程详解,案例群聊系统实现

    1.1为什么要用websocket 如果有需求要实现服务端向客户端主动推送消息时(比如聊天室,群聊室)有哪几种方案 轮训:让浏览器每隔两秒发送一次请求,缺点:有延时,请求太多网站压力大; 长轮训:客户端向服务端发送请求,服务端最多夯20秒,一旦有新的数据就立即返回

    2024年02月02日
    浏览(37)
  • 使用flink实现《实时数据分析》的案例 java版

    本文档介绍了使用Java和Flink实现实时数据分析的案例。该案例使用Flink的流处理功能,从Kafka主题中读取数据,进行实时处理和分析,并将结果输出到Elasticsearch中。 Java 8 Flink 1.13.2 Kafka 2.8.0 Elasticsearch 7.13.4 本案例使用Kafka作为数据源,从一个名为 user_behavior 的主题中读取数据。

    2024年02月08日
    浏览(40)
  • 使用flink实现《实时监控和日志分析》的案例 java版

    本文档介绍了使用Java和Flink实现实时监控和日志分析的案例。该案例旨在通过实时监控和日志分析来提高系统的可靠性和性能。 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kjPKQuIf-1686052913444)(./architecture.png)] 如上图所示,该系统由以下组件组成

    2024年02月06日
    浏览(43)
  • JAVA Socket实现实时接收TCP消息,让你的服务端通信更高效!

    本文主要介绍如何利用socket实现实时接收服务端发送的TCP消息。 目录 一、需要掌握 二、程序源码 三、运行演示 网络调试助手下载:https://www.aliyundrive.com/s/6Y8L7Wv5sT6 网络通信协议的理解:JAVA socket是基于TCP/IP协议实现的,需要对TCP/IP协议有一定的了解,包括TCP连接的建立、数

    2024年02月11日
    浏览(42)
  • Java利用UDP实现简单群聊

    一、创建新项目 首先新建一个新的项目,并按如下操作 二、实现代码 界面ChatFrame类 package 群聊;   import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.net.InetAddress;   public abstract class ChatFrame extends JFrame {     private JTextArea receiveArea = new JTextArea();//接收文本框,用来显示

    2024年02月04日
    浏览(39)
  • 大厂案例 - 实时分析引擎

    网络安全态势越来越复杂,传统的基于单点的防护和攻击检测系统在应对现代网络攻击方面有着很大的局限性。 基于大数据平台,通过流式实时分析技术可以对全局网络空间进行实时的分析和异常检测,解决单点很难发现和处理的安全问题。 相比与互联网公司常见的大数据

    2024年02月16日
    浏览(38)
  • Flink流处理案例:实时数据聚合

    Apache Flink是一个流处理框架,可以处理大规模数据流,实现实时数据处理和分析。Flink支持各种数据源和接口,如Kafka、HDFS、TCP流等,可以实现高吞吐量、低延迟的流处理。 在本文中,我们将通过一个实际的Flink流处理案例来讲解Flink的核心概念、算法原理和最佳实践。我们将

    2024年02月19日
    浏览(46)
  • ClickHouse与Elasticsearch实时搜索案例

    随着数据的增长和实时性的要求,实时搜索技术变得越来越重要。ClickHouse和Elasticsearch都是流行的实时搜索技术,它们各自具有不同的优势和适用场景。本文将详细介绍ClickHouse与Elasticsearch的实时搜索案例,并分析它们的优缺点。 2.1 ClickHouse ClickHouse是一个高性能的列式数据库

    2024年02月19日
    浏览(39)
  • 伴鱼实时数仓建设案例

    随着伴鱼业务的快速发展,离线数据日渐无法满足运营同学的需求,数据的实时性要求越来越高。之前的实时任务是通过实时同步至 TiDB 的数据,利用 TiDB 进行微批计算。随着越来越多的实时场景涌现出来,TiDB 已经无法满足实时数据计算场景,计算和查询都在一套集群中,

    2024年01月22日
    浏览(40)
  • Flink流处理案例:实时数据去重

    在大数据处理领域,实时数据流处理是一项至关重要的技术,可以帮助我们实时分析和处理数据,从而更快地做出决策。Apache Flink是一款流处理框架,具有高性能和低延迟的特点,可以处理大规模的实时数据流。在本文中,我们将讨论Flink流处理的一个案例,即实时数据去重

    2024年04月27日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包