chat2-Client发送数据给Server

本文档描述了Client发送消息给Server, Server端打印接收的消息

一、Client

1.1.客户端的类Client.java中添加如下的start()方法 (表示启动客户端功能的方法),并调用

/**start方法,作为客户端开始工作的方法*/
    public void start(){
        try {
            //Socket提供的方法: OutputStream getOutputStream(),通过该Socket获取
            //一个字节输出流,使用这个流写出的所有字节都会陆续发送给服务端对应的Socket
            OutputStream out = socket.getOutputStream();
            OutputStreamWriter osw = new OutputStreamWriter(out, StandardCharsets.UTF_8);
            BufferedWriter bw = new BufferedWriter(osw);
            PrintWriter pw = new PrintWriter(bw,true);
            Scanner scanner = new Scanner(System.in);
            String nickname;
            while(true){
                System.out.println("请输入昵称:");
                nickname = scanner.nextLine();
                if(nickname.trim().length()>0){
                    pw.println(nickname);
                    break;
                }
                System.out.println("昵称不能为空");
            }
            //启动读取服务端发送过来消息的线程
//            ServerHandler handler = new ServerHandler();
//            Thread t = new Thread(handler);
//            t.setDaemon(true);
//            t.start();

            while(true) {
                String line = scanner.nextLine();
                if("exit".equalsIgnoreCase(line)){
                    break;
                }
                pw.println(line);
            }
        }catch (IOException e) {
            e.printStackTrace();
        } finally {
            try {
                //调用socket的close方法时可以和对方发起四次挥手断开连接
                socket.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

1.2.main方法中调用此方法:

在main方法中添加client.start();

二、Server端:

A.服务端用 ServerSocket 对象开启一个端口。并在 while 循环中调用 ServerSocket 对象的 accept()方法等待客户端连接.

B.如果有客户端连接成功accept()方法会得到一个socket对象。

注: socket对象和服务端对应,里边包含此客户端和服务端对应的输入流和输出流可以用来读服务端发送的数据并给服务端返回数据。

C.将socket对象封装到一个线程中,并用线程池运行此线程中的任务。

2.1.线程池的类

创建线程池的核心类对象:

2.2.编写线程类:

/**该线程任务是负责与指定的客户端进行交互*/
    private class ClientHandler implements Runnable{
        private Socket socket;//服务端的socket包含输出流和输入流用于接收客户端数据并返回输出给客户端
        private String host;//对应客户端的IP地址
        private String nickName;//客户端的昵称
        public ClientHandler(Socket socket){
            this.socket = socket;
            //通过socket获取客户端的ip地址信息
            host = socket.getInetAddress().getHostAddress();
        }
        public void run(){
            try {
                //Socket类中的方法: InputStream getInputStream()
                //通过该Socket对象获取的输入流(可以读取对应客户端发送过来的字节数据)
                InputStream in = socket.getInputStream();
                InputStreamReader isr = new InputStreamReader(in, StandardCharsets.UTF_8);
                BufferedReader br = new BufferedReader(isr);//字节输入流封装为缓冲字符输入流
                //读取一行字符串(是对应客户端发送过来的昵称)
                nickName = br.readLine();
                String message;
                //服务端调用br.readLine()读取客户端发送过来的一行字符串
                //  读取时如果客户端异常断开连接了,则可能出现异常:

//java.net.SocketException: Connection reset
                //  (原因:没有进行四次挥手)
                while ((message = br.readLine()) != null) {
                    System.out.println(nickName + "[" + host + "]说:" + message);
                }
            } catch (IOException e) {
                e.printStackTrace();
                System.err.println(e.getMessage());
            } finally {
                //处理客户端断开连接后的操作
                System.out.println(nickName+"下线了");
                try {
                    //3.将socket关闭,释放资源
                    socket.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }

    }

2.3.启动线程:

用线程池运行此线程中的任务:

运行效果:


                                                                                                   By   zhaoyq   2024-05-31

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

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

相关文章

fastadmin 放服务器上后出现大量的502 亲身经历

fastadmin 放服务器上后出现大量的502 今天发生了一个特别无语的事情,那就是服务器上出现大量的502报错 因为之前一直都运行的好好的,突然今天就开始不间断的报502的错误,最开始我没有怀疑到服务器上,浪费了一天的时间进行排查! 因为域名挂在cf上,然后我又在cf上做了各种…

自然语言处理(NLP)—— 神经网络语言处理

1. 总体原则 1.1 深度神经网络(Deep Neural Network)的训练过程 下图展示了自然语言处理(NLP)领域内使用的深度神经网络(Deep Neural Network)的训练过程的简化图。 在神经网络的NLP领域: 语料…

深入解析Java中List和Map的多层嵌套与拆分

深入解析Java中List和Map的多层嵌套与拆分 深入解析Java中List和Map的多层嵌套与拆分技巧 📝摘要引言正文内容什么是嵌套数据结构?例子: 遍历嵌套List和Map遍历嵌套List遍历嵌套Map 拆分嵌套数据结构拆分嵌套List拆分嵌套Map 🤔 Q…

PHP面向对象编程总结

PHP面向对象编程总结 学习PHP时,面向对象编程(OOP)往往是一个重要的里程碑。PHP的OOP功能提供了一种更加模块化、可扩展和易于维护的代码结构。在本文中,我们将深入探讨PHP面向对象编程的各个方面,包括类与对象、访问控…

【C#】委托和事件

目录 1.概念 2.自定义的委托 3.系统定义的委托 4.委托和事件的区别 1.概念 数组我们都知道是一组数据的容器,而委托很相似,不过它是一组函数的容器。 如果把调用一次函数看做释放一个技能,那调用一次委托则是释放一套技能连招 下面看看…

排序-希尔排序

介绍 希尔排序属于那种没有了解过的直接看代码一脸懵逼的, 所以同学们尽量不要直接看代码,仔细阅读本篇博客内容。 插入排序本来算是一个低效排序, 一次只可以挪动一个数据, 但是,它的强来了!&#xff01…

网吧|基于SprinBoot+vue的网吧管理系统(源码+数据库+文档)

网吧管理系统 目录 基于SprinBootvue的网吧管理系统 一、前言 二、系统设计 三、系统功能设计 1 管理员功能模块 2 网管功能模块 3 会员功能模块 四、数据库设计 五、核心代码 六、论文参考 七、最新计算机毕设选题推荐 八、源码获取: 博主介绍&#…

ASM OMF single-file creation form 重命名

OMF下不能自动命名,需要重新命名的话:1 1. spfile 可以 create pfile from spfile 后再create spfile from pfile 2 redo? 3 datafile? Here are some details of the copy problem: a) You are not allowed to set the numbe…

Arduino 按钮及弹跳

所需元件 可插入面包板的按钮1个 220Ω电阻1个 10kΩ电阻1个 3mm或5mm LED 1个 面包板1块 Arduino Uno开发板1块 面包板连接线数条 使用外接电阻 将5V接到按钮,按钮的另一端串联1个10kΩ电阻再接地,这样的接法被称为下拉电阻(pull-down resistor)。若测…

【30天精通Prometheus:一站式监控实战指南】第14天:jmx_exporter从入门到实战:安装、配置详解与生产环境搭建指南,超详细

亲爱的读者们👋   欢迎加入【30天精通Prometheus】专栏!📚 在这里,我们将探索Prometheus的强大功能,并将其应用于实际监控中。这个专栏都将为你提供宝贵的实战经验。🚀   Prometheus是云原生和DevOps的…

【LeetCode算法】第104题:二叉树的最大深度

目录 一、题目描述 二、初次解答 三、官方解法 四、总结 一、题目描述 二、初次解答 1. 思路:二叉树的先序遍历。首先判断根节点是否是空,其次判断根节点是否是叶子节点,再者递归获取左子树的深度、右子树的深度,最后返回左子…

【Mac】Lightroom Classic 2024(LrC 2024中文版) v13.1安装教程

软件介绍 Lightroom Classic 2024 for Mac是一款功能强大的照片编辑和组织软件,专为专业摄影师和爱好者设计。它提供了一系列工具和功能来增强和管理您的数码照片。Lightroom Classic 2024在照片组织和管理方面进行了重大改进。它新增了一个智能化的“发现”面板&a…

1. MySQL 数据库的基本操作

文章目录 【 1. SQL 的书写规则 】大小写规则常量的表示注释 【 2. RDBMS 术语 】Table 表Filed 域/字段Column 列Record 记录NULL 空值Constraint 约束数据的完整性范式 【 3. 数据库基本操作函数 】3.1 SHOW DATABASES 显示数据库3.2 CREATE DATABASE 创建数据库3.3 ALTER DA…

回炉重造java----JUC(第一天)

目录 JUC前置知识①进程和线程的区别?②并行和并发的区别?③异步调用和同步调用的区别?④创建线程的方法⑤线程的上下文切换⑥TimeUtil⑦Interrupt⑧如何在一个线程中终止另外一个线程?⑨线程的状态共享模型之管程 阻塞式&#x…

LLVM后端__llc中值定义信息的查询方法示例

关于LiveIntervals pass中相关数据结构的含义,在寄存器分配前置分析(5.1) - LiveInterval这篇博客中已经做了清晰的讲解,此处不再赘述,本文主要讲解值定义信息VNInfo的使用方法和注意事项。 1. VNInfo含义 在LLVM的源码中,VNInf…

视频汇聚EasyCVR综合安防平台对接GA/T1400公安视图库及应用方案

随着科技的不断进步,视频监控系统在公共安全领域发挥着越来越重要的作用。GA/T1400公安视图库作为公安视频图像信息应用系统的标准,为视频监控系统的对接提供了统一的规范和技术要求。 GA/T1400标准的应用范围广泛,涵盖了公安系统的视频图像信…

ASM+RAC spfile 恢复 改名

ASMCMD> cd DATA/CDB/PARAMETERFILE ASMCMD> ls spfile.290.1148481317 ASMCMD> rm -rf * ASMCMD> ls srvctl config database -db cdb 不用也可以 [oraclerac1 dbs]$ srvctl modify database -db cdb -spfile ----注释掉 [oraclerac1 dbs]$ srvctl modify da…

YOLOX源码之 wait_for_the_master

主进程读取数据 在函数 get_data_loader 中,下面这段代码的作用是在多节点分布式训练时,每个节点的主进程负责读取数据。 if self.dataset is None:with wait_for_the_master():assert cache_img is None, \"cache_img must be None if you didnt…

Python | A + B问题|||

if语句:if、elif、else 关系运算符 逻辑运算符:and(&&)、or(||)、not(!) break退出循环 continue:只能出现在for、while循环内部,用法…