模拟微信聊天-课后程序(JAVA基础案例教程-黑马程序员编著-第八章-课后作业)

news/2024/3/29 14:47:17/文章来源:https://blog.csdn.net/yw1990128/article/details/129260517

【案例9-1】  模拟微信聊天

【案例介绍】

1.案例描述

在如今,微信聊天已经人们生活中必不可少的重要组成部分,人们的交流很多都是通过微信来进行的。本案例要求:将多线程与UDP通信相关知识结合,模拟实现微信聊天小程序。通过监听指定的端口号、目标IP地址和目标端口号,实现消息的发送和接收功能,并显示聊天的内容。

2.运行结果

运行结果

 

【案例分析】

(1)第一要知道用什么技术实现,通过上述任务描述可知此任务是使用多线程与UDP通信相关知识实现的。要实现图中的聊天窗口界面。首先需要定义一个实现微信聊天功能的类,类中需要定义访问微信聊天的输出语句,从而获取输入的发送端端口号、接收端端口号以及实现发送和接收功能的方法。

(2)实现发送数据的功能。该功能通过一个实现了Runnable接口的类实现,类中需要定义获取发送数据的端口号,并在实现run()的方法中,编写发送数据的方法。

(3)实现接收数据的功能。该功能通过一个实现了Runnable接口的类实现,类中需要定义获取接收数据的端口号,并在实现run()的方法中,编写显示接收到的数据的方法。

(4)创建完所有的类与方法后,运行两次程序,同时开启两个窗口来实现聊天功能。

【案例实现】

(1)创建微信聊天程序,开启两个聊天窗口,需要创建两个聊天程序。两个聊天程序代码分别如下所示。

Room.java

  1. package chapter090;
  2. import java.util.Scanner;
  3. public class Room {
  4.     public static void main(String[] args) {
  5.         System.out.println("微信聊天欢迎您!");
  6.         Scanner sc = new Scanner(System.in);
  7.         System.out.print("请输入您的微信号登录:");
  8.         int sendPort = sc.nextInt();
  9.         System.out.print("请输入您要发送消息的微信号:");
  10.         int receivePort = sc.nextInt();
  11.         System.out.println("微信聊天系统启动!!");      
  12.          //发送操作
  13.         new Thread(new SendTask(sendPort), "发送端任务").start();
  14.          //接收操作
  15.         new Thread(new ReceiveTask(receivePort), "接收端任务").start();
  16.     }
  17. }

上述代码中,第12行代码用多线程实现发送端口号以及实现发送端功能的方法。第14行代码用多线程实现接收端口号以及实现接收端功能的方法。

Lucy.java

  1. package chapter090;
  2. import java.util.Scanner;
  3. public class Lucy {
  4. public static void main(String[] args) {
  5.     System.out.println("微信聊天欢迎您!");
  6.     Scanner sc = new Scanner(System.in);
  7.     System.out.print("请输入您的微信号登录:");
  8.     int sendPort = sc.nextInt();
  9.     System.out.print("请输入您要发送消息的微信号:");
  10.     int receivePort = sc.nextInt();
  11.     System.out.println("微信聊天系统启动!!");
  12.     //发送操作
  13.     new Thread(new SendTask(sendPort), "发送端任务").start();
  14.     //接收操作
  15.     new Thread(new ReceiveTask(receivePort), "接收端任务").start();
  16. }
  17. }

(2)创建发送数据的任务类,其代码如下所示。

SendTask.java

    1. package chapter0901;
    2. import java.net.DatagramPacket;
    3. import java.net.DatagramSocket;
    4. import java.net.InetAddress;
    5. import java.util.Scanner;
    6. public class SendTask implements Runnable {
    7.     private int sendPort; // 发数据的端口号
    8.     // 构造方法
    9.     public SendTask(int sendPort) {
    10.         this.sendPort = sendPort;
    11.     }
    12.     @Override
    13.     public void run() {
    14.         try {
    15.            // 1. 创建DatagramSocket对象
    16.            DatagramSocket ds = new DatagramSocket();
    17.            // 2.输入要发送的数据
    18.            Scanner sc = new Scanner(System.in);
    19.            while (true) {
    20.                String data = sc.nextLine();// 获取键盘输入的数据
    21.                // 3.封装数据到 DatagramPacket对象中
    22.            byte[] buf = data.getBytes();
    23.            DatagramPacket dp = new DatagramPacket(buf, buf.length,
    24.             InetAddress.getByName("127.0.0.255"),sendPort);
    25.                // 4.发送数据
    26.                ds.send(dp);
    27.            }
    28.         } catch (Exception e) {
    29.            e.printStackTrace();
    30.         }
    31.     }
    32. }

上述代码中,第6~10行代码声明了一个名称为sendPort的变量表示发送数据的端口号,并通过该类的构造方法获取所输入的端口号。第12~29行代码,实现run()方法,在run()方法中,首先创建了DatagramSocket对象,然后通过Scanner对象和循环方法获取键盘输入的数据,并将获取的数据封装到了DatagramPacket对象中,最后通过DatagramSocket对象的send()方法发送数据。在循环方法中,由于发送数据时可能多次连续发送,所以将循环条件设置为true,表示不断循环获取和发送数据。在创建DatagramPacket对象时,为了让当前局域网的所有人都接收到消息,所以将IP地址设置为127.0.0.255。

(3)创建接收数据的任务类,其代码如下所示。

ReceiveTask.java

  1. package chapter090;
  2. import java.net.DatagramPacket;
  3. import java.net.DatagramSocket;
  4. public class ReceiveTask implements Runnable{
  5.     private int receivePort;// 接收数据的端口号
  6.     public ReceiveTask(int receivePort) {
  7.         this.receivePort = receivePort;
  8.     }
  9.     @Override
  10.     public void run() {
  11.         try {
  12.            // 1.DatagramSocket对象
  13.            DatagramSocket ds = new DatagramSocket(receivePort);
  14.            // 2.创建DatagramPacket对象
  15.            byte[] buf = new byte[1024];
  16.            DatagramPacket dp = new DatagramPacket(buf, buf.length);
  17.            // 3.接收数据
  18.            while (true) {
  19.                ds.receive(dp);
  20.                // 4.显示接收到的数据
  21.                String str = new String(dp.getData(), 0,
  22.                                                dp.getLength());
  23.                System.out.println("收到" +
  24.                    dp.getAddress().getHostAddress()
  25.                 + "--发送的数据--" + str);
  26.            }
  27.         } catch (Exception e) {
  28.            e.printStackTrace();
  29.         }
  30.     }
  31. }

上述代码中,第4行代码声明了一个名称为receivePort的变量来表示接收数据的端口号,第5~7行代码定义一个该类的构造方法,并通过该类的构造方法获取所输入的端口号,第9~28行代码在run()方法中,首先创建了DatagramSocket对象,创建该对象时需要传入接收数据的端口号,然后创建用于接收数据的DatagramPacket对象,接下来通过循环的方法来接收数据,最后通过输出语句来显示接收到的数据。

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

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

相关文章

微电影广告的内容突破方案

微电影作为新媒体时代背景的产物,深受大众的欢迎,同时,微电影广告在微电影模式环境下应运而生,以自己独特的传播优势,俘获了大量企业主的青睐,也获得了广大青年群体的喜爱。微电影广告欲确保可持续发展&…

springboot+pgbouncer+postgres数据库连接池集成方案及问题解决

期望通过每一次分享,让技术的门槛变低,落地更容易。 —— around 前言 旨在解决微服务项目全是连接池并影响数据库并发连接,作者的环境是基于sprongboot微服务连接postgres数据库,每个微服务的DAO层配置都使用了连接池技术。后续…

PGLBox 超大规模 GPU 端对端图学习训练框架正式发布

作者 | PGLBox项目组 导读 PGLBox是百度研发的基于GPU的大规模图模型训练框架,支持数百亿节点和边的图模型全GPU训练,已在百度广泛部署。相比业界主流的分布式 CPU 解决方案,PGLBox 具有超高性能、超大规模、算法丰富、灵活易用、落地广泛等优…

复习知识点十之方法的重载

目录 方法的重载 练习1: 练习1: 数组遍历 练习2: 数组的最大值 练习3: 练习4: 复制数组 基本数据类型和引用数据类型 方法的重载 Java虚拟机会通过参数的不同来区分同名的方法 练习1: public class Test4 {public static void main(String[] args) {//调用方法 // …

【架构师】零基础到精通——服务与网关

博客昵称:架构师Cool 最喜欢的座右铭:一以贯之的努力,不得懈怠的人生。 作者简介:一名Coder,软件设计师/鸿蒙高级工程师认证,在备战高级架构师/系统分析师,欢迎关注小弟! 博主小留言…

Raki的读paper小记:BART

Abstract&Introduction&Related Work 研究任务 预训练语言模型已有方法和相关工作 BERT等面临挑战 已有的方法依赖下游任务创新思路 融合了双向和自回归模型随机打乱原始句子的顺序,并同时使用一种novel的填空方案,文本的span只用一个masked to…

近期常见组件漏洞更新:

(1)mysql 5.7 在2023年1月17日,发布了到5.7.41版本 mysql 8.0 在2023年1月17日,发布了到8.0.32版本 MySQL :: Download MySQL Community Serverhttps://dev.mysql.com/downloads/mysql/ (2)Tomcat8在202…

RedisTemplate 的基本使用手把手教

下载实例源码 使用步骤 1、引入 spring-boot-starter-data-redis 依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-redis</artifactId> </dependency>2、在 application.yml 配置 R…

springboot使用Gateway搭建网关服务及Nacos实现动态路由

实际工作中我们会有很多个项目&#xff0c;这些项目共同使用同一个网关gateway来实现路由&#xff0c;各个项目之间调用以及前端调用都可以直接通过服务名称来调用&#xff0c;不用管ip&#xff0c;后续项目迁移到其它服务器也不受影响。 首先搭建springboot微服务&#xff0c…

CANoe TC8测试脚本的结构介绍

CANoe TC8脚本是通过vTESTstudio平台编写。每个协议(ARP\ICMPv4\IPv4\UDP\TCP\SOMEIP\DHCP)都有自己的vtt文件。每个vtt文件的测试树结构为: Test Fixture Fixture Preparation Test Case Test Case … Test Case Test Case Fixture Completion 当Test Fixture里的Test Case…

分布式ID生成系统

目录背景常用分布式ID生成系统介绍UUIDSnowflake背景 在大多数复杂的分布式系统中&#xff0c;往往需要对大量的数据和消息进行唯一标识。而对分布式系统后台数据库的分库分表后需要有一个唯一的ID来表示一条数据或者是消息。那么我们分布式系统ID一般都有哪些需求呢&#xff1…

初识CSS

1.CSS语法形式CSS基本语法规则就是:选择器若干属性声明由选择器选择一个元素,其中的属性声明就作用于该元素.比如:<body><p>这是一个段落</p><!-- style可以放在代码的任意地方 --><style>p{/* 将字体颜色设置为红色 */color: red;}</style&g…

C++修炼之练气期一层——命名空间

目录 1.引例 2.命名空间的定义 3.命名空间的使用 4.命名空间使用注意事项 1.引例 #include <stdio.h> #include <stdlib.h>int rand 10;int main() {printf("%d\n", rand);return 0; } 当我们用C语言写下这样的代码&#xff0c;看着并没有什么语法…

【手把手一起学习】(七) Altium Designer 20常用PCB设计规则

1 常用PCB设计规则 PCB规则设计是PCB设计中至关重要的环节&#xff0c;它约束了电气要求、布线方式、器件摆放位置等&#xff0c;为后续的手动布局、布线提供依据。完善的PCB规则设计&#xff0c;可以减少设计中的错误&#xff0c;提高PCB设计效率。 1.1 PCB设计规则管理器 …

谷歌搜索技巧大全 | 谷歌高级搜索语法指令

谷歌搜索技巧是利用各种高级搜索语法或者搜索指令&#xff0c;让我们能够使用Google进行精确化的搜索&#xff0c;外贸找客户和学术文件查找都可以应用到这些搜索技巧。(大部分命令也适用百度搜索)。Google通过互联网收集数据&#xff0c;抓取有意义的信息&#xff0c;将其存储…

【知识图谱】架构-特点-缺点简介

架构物联网、云计算、人工智能等新一代信息技术的迅猛发展&#xff0c;带来了制造业的新一轮突破&#xff0c;推动着制造系统向智能化方向发展&#xff0c;驱动着未来制造模式的创新。其中数据和知识是实现制造业与新一代信息技术融合的基础&#xff0c;是实现智能制造的保障。…

C++杂谈(一)

前言 本系列也是慢更系列&#xff0c;主要收纳一些还不够单独成系列的C的杂项问题&#xff0c;或是一些与C有关&#xff0c;但不属于核心知识的一些旁系问题。 关于C与C的关系 「学C要先学C吗&#xff1f;」 「C和C是不是完全不同的两个语言&#xff1f;」 「这个语法是C的还…

Android 动画详解

Android动画的分类与使用学习Android必不可少的就是动画的使用了&#xff0c;在Android版本迭代的过程中&#xff0c;出现了很多动画框架&#xff0c;这里做一个总结。Android动画类型分类逐帧动画【Frame Animation】&#xff0c;即顺序播放事先准备的图片。补间动画【Tween A…

NSGA-Ⅲ源代码

NSGA-Ⅲ源代码如下&#xff0c;供大家学习和应用。该算法在梯级水电-火电的应用订阅专栏即可查看&#xff1a; 1、主函数 % % Copyright (c) 2016, Mostapha Kalami Heris & Yarpiz (www.yarpiz.com) % All rights reserved. Please read the "LICENSE" file…

前端经典react面试题及答案

为什么 React 元素有一个 $$typeof 属性 目的是为了防止 XSS 攻击。因为 Synbol 无法被序列化&#xff0c;所以 React 可以通过有没有 $$typeof 属性来断出当前的 element 对象是从数据库来的还是自己生成的。 如果没有 $$typeof 这个属性&#xff0c;react 会拒绝处理该元素。…