Java网络通讯案例——即时通讯(控制台版)

news2024/11/15 11:19:02

一、需求分析

  • 用户与用户之间1-1或1-n通讯

二、技术分析
(一)客户端

  • 客户端的功能有两个:发消息和接消息
  • 发消息:使用Socket技术的流式输出,配合打印流封装发送。
  • 接信息:使用读取专用线程,搭配字符缓冲流读取。

(二)服务端

  • 服务端的功能:转发消息。
  • 实现转发功能:
    • 1、创建服务通道ServerSocket
    • 2、建立线程池ExecutorService->ThreadPoolExecutor
    • 3、等待连接
    • 4、向集合添加通道对象
    • 5、添加转发任务到线程池任务队列
    • 6、转发线程类的重写
      • 第 1 部分:接收信息: 字符缓冲流读取接收的信息。
      • 第 2 部分:转发信息: 遍历所有通道,获取输出流输出数据。

三、实现代码
客户端

class Client1{
    public static void main(String[] args) {
        try {
            //建立通道
            Socket sender = new Socket(InetAddress.getLocalHost().getHostAddress(),7777);

            new ClientServiceThread(sender).start();

            Scanner in = new Scanner(System.in);

            if (sender.isConnected()) System.out.println(sender.getRemoteSocketAddress() + " 已连接!");

            //输出流
            PrintStream outStream = new PrintStream(sender.getOutputStream(),true);
            String message;
            while(!(message = in.nextLine()).equals("exit")){
                outStream.println(message);
            }

        } catch (IOException e) {
            System.out.println("连接已断开");
        }
    }
}

class Client2{
    public static void main(String[] args) {
        try {
            //建立通道
            Socket sender = new Socket(InetAddress.getLocalHost().getHostAddress(),7777);

            new ClientServiceThread(sender).start();

            Scanner in = new Scanner(System.in);

            if (sender.isConnected()) System.out.println(sender.getRemoteSocketAddress() + " 已连接!");

            //输出流
            PrintStream outStream = new PrintStream(sender.getOutputStream(),true);
            String message;
            while(!(message = in.nextLine()).equals("exit")){
                outStream.println(message);
            }

        } catch (IOException e) {
            System.out.println("连接已断开");
        }
    }
}

class ClientServiceThread extends Thread{

    private Socket socket;

    public ClientServiceThread(){}

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

    @Override
    public void run() {
        try {
            InputStream in = socket.getInputStream();

            BufferedReader br = new BufferedReader(new InputStreamReader(in));

            String message;

            while((message = br.readLine()) != null){
                System.out.println(socket.getRemoteSocketAddress() + " " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()));
                System.out.println(message);
            }
        } catch (IOException e) {
            System.out.println("服务器将您踢出群聊······");
        }
    }
}

服务端

class Server{
    public static List<Socket> sockets = new ArrayList<>();

    public static void main(String[] args) {
        try {
            ServerSocket socket = new ServerSocket(7777);
            ExecutorService service = new ThreadPoolExecutor(3,5,5, TimeUnit.SECONDS,new LinkedBlockingDeque<>(4),new ThreadPoolExecutor.AbortPolicy());

            while(true){
                Socket accept = socket.accept();
                System.out.println(accept.getRemoteSocketAddress() + "已上线!时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()));
                sockets.add(accept);
                service.execute(new ServerThread(accept));
            }

        } catch (IOException e) {
            System.out.println();
        }
    }
}

class ServerThread implements Runnable{

    private Socket socket;

    public ServerThread() {
    }

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

    @Override
    public void run() {
        try {
            BufferedReader reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
            System.out.println(socket.getRemoteSocketAddress() + " 已上线,上线时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(System.currentTimeMillis()));
            String message;
            while((message = reader.readLine())!=null){
                //获取信息
                System.out.println(socket.getRemoteSocketAddress() + " " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
                System.out.println(message);

                //使用转发技术,转发其它客户端
                sendMessageAll(message);
            }
        } catch (IOException e) {
            System.out.println(socket.getRemoteSocketAddress() + ",下线了,时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
            Server.sockets.remove(socket);
        }
    }

    private void sendMessageAll(String message) {
        for (Socket socket :Server.sockets) {
            try {
                PrintStream ps = new PrintStream(socket.getOutputStream(),true);
                ps.println(message);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

效果图

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

usmile笑容加新品发布,可视化定义电动牙刷未来发展路径?

历经20余年的发展&#xff0c;中国电动牙刷市场以外资品牌入华为肇始&#xff0c;到目前已经呈现出品牌林立、供给丰富&#xff0c;且国产品牌开始后来者居上的局面。 但近年来行业高速发展的势头似乎有所收敛&#xff0c;与此同时&#xff0c;市场还具备广阔的可拓展空间。数…

M.2 SSD接口详解

一、M.2简介 M.2接口是一种新的主机接口方案&#xff0c;可以兼容多种通信协议&#xff0c;如sata、PCIe、USB、HSIC、UART、SMBus等。 M.2接口是为超极本&#xff08;Ultrabook&#xff09;量身定做的新一代接口标准&#xff0c;以取代原来的mSATA接口。无论是更小巧的规格尺…

【Web服务应用】Tomcat部署

Tomcat部署 一、Tomcat简介二、tomcat组件2.1核心组件2.2Tomcat功能组件2.3Tomcat 请求过程 三、部署Tomcat服务3.1Tomcat虚拟主机配置 四、Tomcat多实例部署 一、Tomcat简介 一款 java 开发的开源的 Web 应用服务程序。 可以作为Web应用服务器&#xff0c;处理静态的Web页面&…

比别人更快,更优秀的测试方法!(持续更新)

目录 css selector 应用场景 场景&#xff1a;假设有100个商品要添加&#xff0c;但是没有全选按钮&#xff0c;怎么办&#xff1f; 模拟微信UserAgent设置 场景&#xff1a;模拟微信打开H5 VPN下如何抓包 场景&#xff1a;APP需要开启VPN代理才能正常访问&#xff0c;同时…

NEEPUSec CTF 2023 easymath

easymath 题目描述&#xff1a; from Crypto.Util.number import *flagbytes_to_long(bNeepu{xxx})N 738931348122338421499476261982330058997842307585754071200798137388701886017484620800095723028366934218646065252158059518352370641258869511690690571844077077623…

聊聊TCP协议的粘包、拆包以及http是如何解决的?

目录 一、粘包与拆包是什么&#xff1f; 二、粘包与拆包为什么发生&#xff1f; 三、遇到粘包、拆包怎么办&#xff1f; 解决方案1&#xff1a;固定数据大小 解决方案2&#xff1a;自定义请求协议 解决方案3&#xff1a;特殊字符结尾 四、HTTP如何解决粘包问题的&#xf…

Nginx踩坑记录(二) nginx: [warn] invalid value “TLSv1.3“ in /etc/nginx/nginx.conf:20

问题详情 &#xff08;通过指定配置文件的方式&#xff09;启动nginx&#xff0c;提示告警&#xff0c;nginx启动失败。 rootvultr:~# nginx -c /etc/nginx/conf/nginx.conf nginx: [warn] invalid value "TLSv1.3" in /etc/nginx/conf/conf.d/v2ray.conf:20问题原…

高校学生公寓数字化安全用电管理系统解决方案

摘要 本文针对高校学生公寓用电特点,从安全用电角度提出了一套集用电管理、计量、恶性负载智能识别控制、实时跟踪检测等功能于一体的数字化安全用电管理系统技术解决方案———学生公寓智能控电管理系统。 关键词:公寓恶性负载安全用电智能系统 0、引言 近年来,为了响应国…

chatgpt赋能python:Python后处理:优化你的SEO

Python后处理&#xff1a;优化你的SEO 在今天的数字世界中&#xff0c;SEO是任何成功的企业或网站的必要元素之一。搜索引擎优化不仅可以帮助你的网站排名更高&#xff0c;还可以影响你的流量和销售。因此&#xff0c;为了优化SEO表现&#xff0c;很多企业和网站都把目光投向了…

2个月过去了,面试至今0 offer,这是怎么了?

转眼已是6月初&#xff0c;求职招聘季也结束啦&#xff0c;如果没点真技术、真本事&#xff0c;不了解点职场套路&#xff0c;在今年行情下&#xff0c;找工作可是难上加难。 现在点开微博或者脉脉&#xff0c;只要搜索“招聘”&#xff0c;用“惨不忍睹”来形容也不为过。不少…

windows11安装docker desktop实现docker环境

简介 我们知道docker的安装一般我们是安装在linux系统上的&#xff0c;但是如果你的宿主机是windows&#xff0c;那么你还想装docker&#xff0c;那么就需要现在你的windows上装上虚拟机&#xff0c;虚拟机上装linux操作系统&#xff0c;然后在Linux操作系统上再去安装docker&…

【ECCV2022】DaViT: Dual Attention Vision Transformers

DaViT: Dual Attention Vision Transformers, ECCV2022 解读&#xff1a;【ECCV2022】DaViT: Dual Attention Vision Transformers - 高峰OUC - 博客园 (cnblogs.com) DaViT&#xff1a;双注意力Vision Transformer - 知乎 (zhihu.com) DaViT: Dual Attention Vision Trans…

在线教育APP小程序系统开发 教培行业一站式解决方案

移动互联网如今已经深入到我们生活的方方面面&#xff0c;教育行业也不例外。如今市面上的在线教育APP小程序系统开发大受欢迎&#xff0c;很多学校、培训机构等都争相开发应用软件&#xff0c;以求通过全新的模式来满足不断扩大的市场需求&#xff0c;为用户提供更高质量的服务…

约瑟夫环(递归+迭代)

剑指 Offer 62. 圆圈中最后剩下的数字 leetcode 这题让我对递归和迭代又有了新的一层认识&#xff0c;首先一定要把图画对&#xff0c;就是模拟约瑟夫的这个过程 红色是被淘汰的位置&#xff0c;绿色的3是最后会活下来的人的位置 0 ~ n 正好是数组中的下标 重点在于计算 不同…

Java009——Java数据类型简单认识

围绕以下3点学习&#xff1a; 1、什么是Java数据类型&#xff1f; 2、Java数据类型的作用&#xff1f; 3、Java有哪些数据类型&#xff1f; 4、熟悉Java8大基本数据类型 一、什么是Java数据类型&#xff1f; 当我们写Java代码时&#xff0c;需要把数据保存在变量&#xff08;…

【备战秋招】每日一题:4月8日美团春招(三批)第一题:题面+题目思路 + C++/python/js/Go/java带注释

2023大厂笔试模拟练习网站&#xff08;含题解&#xff09; www.codefun2000.com 最近我们一直在将收集到的各种大厂笔试的解题思路还原成题目并制作数据&#xff0c;挂载到我们的OJ上&#xff0c;供大家学习交流&#xff0c;体会笔试难度。现已录入200道互联网大厂模拟练习题&…

Unity之反向动力学IK

1、如何使用 &#xff08;1&#xff09;给物体的父对象加上IK Manager的脚本 &#xff08;2&#xff09;在人物四肢骨骼末端和权杖末端创建空对象 &#xff08;3&#xff09;添加IK节点 选择Player 添加后会发现出现了一个Player的子对象IK节点 将权杖末端的GameObject拖入…

deepin搭建go开发环境(git、go、neovim、NvChad、Nerd Font)

安装deepin虚拟机 官网下载地址 vmware中记得版本选择是debian 10.x 64位 然后就是一些确认操作&#xff0c;然后就可以了 安装git apt install gedit apt install git git config --global user.name "hello" git config --global user.email hello126.com git c…

Nginx之location与rewrite

Nginx之location与rewrite 一.location location 对访问的路径做访问控制或者代理转发1.匹配分类 精准匹配&#xff1a; location / {...} 前缀匹配&#xff1a; location ^~ / {...} 正则匹配&#xff1a; location ~ / {...} location ~* / {...} 部分…

直播带货APP小程序系统开发功能有哪些?

直播带货APP小程序系统开发功能有哪些&#xff1f; 1、直播带货&#xff1a;主播一边带货一边直播间活跃气氛&#xff0c;直观地了解产品&#xff0c;下单的概率会更高。还集有观看、打赏、购物、分享于一体。 2、短视频带货&#xff1a;短视频种草&#xff0c;利…