[进阶]TCP通信综合案例:群聊

 代码演示如下:

客户端:

public class Client {
    public static void main(String[] args) throws Exception{
        System.out.println("客户端开启!");
        //1.创建Socket对象,并同时请求与服务端程序的连接。
        Socket socket = new Socket("127.0.0.1",8888);

        //创建一个独立的线程,负责随时从socket中接收服务端发送过来的消息
        new ClientReaderThread(socket).start();

        //2.从socket通信管道中得到一个字节输出流。用来发数据给服务端程序
        OutputStream os = socket.getOutputStream();
        //3.把低级的字节输出流包装成数据输出流
        DataOutputStream dos = new DataOutputStream(os);

        Scanner sc = new Scanner(System.in);
        while (true) {
            System.out.println("请输入:");
            String msg = sc.nextLine();

            //一旦用户输入了exit,就退出客户端程序
            if ("exit".equals(msg)){
                System.out.println("退出成功!");
                dos.close();
                socket.close();
                break;
            }
            //4.开始写数据出去了
            dos.writeUTF(msg);
            dos.flush();
        }
    }
}

服务端:

public class Server {
    public static List<Socket> onLineSockets = new ArrayList<>();
    public static void main(String[] args) throws Exception{
        System.out.println("服务端开启!");
        //1.创建ServerSocket的对象,同时为服务端注册端口。
        ServerSocket serverSocket = new ServerSocket(8888);
        while (true) {
            //2.使用serverSocket对象,调用一个accept方法,等待客户端的连接请求
            Socket socket = serverSocket.accept();
            onLineSockets.add(socket);
            System.out.println("有人上线了:" + socket.getRemoteSocketAddress());
            //3.把这个客户端对应的socket通信管道,交给一个对立的线程负责处理
            new ServerReaderThread(socket).start();
        }
    }
}

客户端线程类:

public class ClientReaderThread extends Thread{
    private Socket socket;
    public ClientReaderThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run(){
        try {
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                try {
                    String msg = dis.readUTF();
                    System.out.println(msg);
                } catch (Exception e) {
                    dis.close();
                    socket.close();
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

服务端线程类:

public class ServerReaderThread extends Thread{
    private Socket socket;
    public ServerReaderThread(Socket socket){
        this.socket = socket;
    }
    @Override
    public void run(){
        try {
            InputStream is = socket.getInputStream();
            DataInputStream dis = new DataInputStream(is);
            while (true) {
                try {
                    String msg = dis.readUTF();
                    System.out.println(msg);
                    //把这个消息分发给客户端进行接收
                    sendMsgToALL(msg);
                } catch (Exception e) {
                    System.out.println("有人下线了:"+ socket.getRemoteSocketAddress());
                    dis.close();
                    socket.close();
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    private void sendMsgToALL(String msg) throws Exception {
        // 发送给全部在线的socket管道接收
        for (Socket onLineSocket : Server.onLineSockets) {
            OutputStream os = onLineSocket.getOutputStream();
            DataOutputStream dos = new DataOutputStream(os);
            dos.writeUTF(msg);
            dos.flush();
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/30926.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

新人拿到一个web项目如何使用idea发布运行

本文描述的是一个新手&#xff0c;拿到一个web项目&#xff0c;使用idea如何发布运行。项目中没有非常复杂的元素&#xff0c;只是试着描述应该如何配置相关内容。 内容描述前提&#xff0c;首先请您确认tomcat已经安装&#xff0c;其次确认jdk已经安装&#xff0c;并明确他们在…

STM32速成笔记—GPIO

文章目录 一、什么是GPIO二、GPIO的输入/输出模式三、GPIO初始化配置四、Boot引脚五、一些特殊的GPIO六、点亮LED1. 硬件电路2. 拉高/拉低GPIO3. 程序设计 七、GPIO的位带操作 一、什么是GPIO GPIO(英语:General-purpose input/output)&#xff0c;通用型之输入输出的简称&…

Java与SpringBoot对redis的使用方式

目录 1.Java连接redis 1.1 使用Jedis1.2 使用连接池连接redis1.3 java连接redis集群模式 2.SpringBoot整合redis 2.1 StringRedisTemplate2.2 RedisTemplate 1.Java连接redis redis支持哪些语言可以操作 &#xff08;去redis官网查询&#xff09; 1.1 使用Jedis (1)添加jedis…

【数字图像处理】2.几何变换

目录 什么是几何变换&#xff1f; 为什么要对图像进行几何变换&#xff1f; 2.1 仿射变换&#xff08;二维&#xff09; 2.2 投影变换&#xff08;三维&#xff09; 2.3 极坐标变换 2.3.1 将笛卡尔坐标转化为极坐标 2.3.2 将极坐标转换为笛卡尔坐标 2.3.3 利用极坐标变…

汇编学习教程:寻址大总结

前言 在上篇博文中&#xff0c;我们主要学习了一个全新的寄存器&#xff1a;bp。bp 寄存器在功能和使用上与 bx 有着异曲同工之妙&#xff0c;只不过两人绑定的服务对象不同&#xff1a;bx 默认绑定的是 DS 段寄存器&#xff0c;而 bp 默认绑定的是 SS 段寄存器。bx 和 bp 有着…

Unity之透明度混合与ps的透明度混合计算结果不一致

一、问题 前段时间学习shader时发现了一个问题&#xff0c;一张纯红色透明度为128的图片叠加在一张纯绿色的图片上得出的结果与ps中的结果不一致。网上查找了ps中的透明混合的公式为 color A.rgb*A.alpha B.rgb*(1-A.alpha)。自己使用代码在unity中计算了一下结果总是不对。…

【Java基础学习打卡09】JRE与JDK

目录 前言一、JRE二、JDK三、JDK、JRE和JVM关系总结 前言 本文将介绍JRE、JDK是什么&#xff0c;以及JDK、JRE和JVM关系三者之间的关系。 一、JRE JRE全称为Java Runtime Environment&#xff0c;是Java应用程序的运行时环境。JRE包括Java虚拟机&#xff08;JVM&#xff09;、…

车辆救援道路救援预约汽修托运小程序

道路救援&#xff1a;指汽车道路紧急救援&#xff0c;为故障车主提供包括诸如&#xff1a;拖吊、换水、充电、换胎、送油以及现场小修等服务(Road-Side Service)&#xff1b; 同时也指交通事故道路救援&#xff0c;包括伤员救治、道路疏导等。 随着我国巨大的汽车拥有量&…

基础篇:新手使用vs code新建go项目(从0开始到运行)

学习新语言&#xff0c;搭建新环境。在网上找了一些教程&#xff0c;感觉还是写一个比较详细的方便以后自己使用。其实vs code没有新建项目这个功能&#xff0c;具体怎么运行go语言的项目请看下文。 一、下载GO安装包 1.点击go安装包下载链接下载相应的版本&#xff08;本次下…

了解 Dockerfile 和搭建 Docker 私有仓库:让容器化部署变得更简单

目录 1、Dockerfile 1.1什么是Dockerfile 1.2常用命令 1.3使用脚本创建镜像 2、Docker私有仓库 2.1私有仓库介绍&#xff1a; 2.2私有仓库搭建与配置 2.3上传镜像到私有仓库&#xff1a; 1、Dockerfile 1.1什么是Dockerfile Dockerfile是由一些列命令和参数构成的脚本…

《网络安全0-100》安全事件案例

网络安全事件案例分析 2017年Equifax数据泄露事件 Equifax是美国一家信用评级机构&#xff0c;2017年9月&#xff0c;该公司披露发生了一起重大的数据泄露事件&#xff0c;涉及1.43亿美国人的个人信息&#xff0c;包括姓名、出生日期、社会安全号码等敏感信息。经过调查&#…

【数据分析】如何使用docker部署程序并移植(算法、接口)

原文作者&#xff1a;我辈李想 版权声明&#xff1a;文章原创&#xff0c;转载时请务必加上原文超链接、作者信息和本声明。 文章目录 前言一、Docker的基本使用1.安装Docker2.列出本地镜像3.获取镜像,创建本地ubuntu:13.10镜像4.查找镜像5.删除本地镜像6.创建自定义镜像7.镜像…

第一章 基础算法(二)——高精度,前缀和与差分

文章目录 高精度运算高精度加法高精度减法高精度乘法高精度除法 前缀和二维前缀和 差分二维差分 高精度练习题791. 高精度加法792. 高精度减法793. 高精度乘法794. 高精度除法 前缀和练习题795. 前缀和796. 子矩阵的和 差分练习题797. 差分798. 差分矩阵 高精度运算 两个大数做…

【Unity Shader】从入门到感慨(2)用C#画一个立方体

文章目录 一、构成一个立方需要多少个顶点?二、定义三角面的索引数组:三、定义UV坐标数组:四、最后构建Mesh:五、完整代码:一、构成一个立方需要多少个顶点? 这个问题是面试经常被问到的题。如上图,我们知道在几何中立方体有6个面,8个顶点。但在图形学中,顶点指的是模…

翻过那座山——Gitlab流水线任务疑难之编译有子模块的项目指南

&#x1f4e2;欢迎点赞 &#xff1a;&#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff0c;赐人玫瑰&#xff0c;手留余香&#xff01;&#x1f4e2;本文作者&#xff1a;由webmote 原创&#x1f4e2;作者格言&#xff1a;新的征程&#xff0c;我们面对的不是…

QT入门基础知识

什么是QT QT是一个跨平台的C图像用户界面应用程序框架QT在1991年由奇趣科技开发QT的优点 跨平台,几乎支持所有平台接口简单&#xff0c;容易上手一定程度上简化了内存回收机制有很好的社区氛围可以进行嵌入式开发 QWidget QT注意事项 命名规范 类名 首字母大写&#xff0c;单…

golang vscode环境报错gopls was not able to find modules in your workspace的解决方式

目录 错误提示 分析 解决方式 方法一&#xff1a;将workspace与项目路径保持一致 方案二&#xff1a;使用go work指明纳入工作区的的module 总结 错误提示 golang从老版本升级到go1.20.5后打开vscode&#xff0c;发现代码不能自动补全了&#xff0c;而且vscode跳出一下的…

微服务基础介绍

Part1一、基本概念 微服务最主要的功能是根据业务拆分成一个一个的子服务&#xff0c;实现功能的去耦合&#xff0c;每一个微服务提供单个业务功能的服务&#xff0c;各司其职&#xff0c;从技术角度看就是一种灵活独立的单元&#xff0c;能够自行单独启动和关闭&#xff0c;一…

Docker学习笔记1

PaaS&#xff1a; 一、虚拟化分类&#xff1a; 虚拟化资源提供者&#xff1a; 1&#xff09;硬件平台虚拟化 2&#xff09;操作系统虚拟化 虚拟化实现方式&#xff1a; type I: 半虚拟化 type II&#xff1a;硬件辅助全虚拟化 type III&#xff1a; 软件全虚拟化&#xff1a; …

【C++】模版进阶

目录 一、非类型模版参数二、模板的特化1、概念2、函数模版特化3、类模板特化1.全特化2.偏特化3.类模板特化应用示例 三、模版分离编译1、什么是分离编译2、模板的分离编译3、模板的优缺点 一、非类型模版参数 模版参数分为类型模版参数与非类型模版参数 类型模版参数&#x…