Java——网络编程(下)

news2025/2/24 8:58:31

(UDP通讯的实现)

1 UDP通信介绍

(面向无链接的一个传输协议——>不会创建连接——>效率高)

(发送数据要经行封包操作——>使用DatagramPacket类——>底层是UDP)

(DatagramPacket——>数据封包——>发送数据和接收数据都要去包装对象!!!必须是字节数组!!!——接收2个参数,发送4个参数)

(DatagramSocket——>发送或接收数据报包)

(注意这两个类的方法,构造方法,UDP通信编程基本步骤)








1 和TCP的区别

UDP协议与之前讲到的TCP协议不同,是面向无连接的,双方不需要建立连接便可通信。UDP通信所发送的数据需要进行封包操作(使用DatagramPacket类),然后才能接收或发送(使用DatagramSocket类)。
在这里插入图片描述



2 DatagramPacket:数据容器(封包)的作用

此类表示数据报包。 数据报包用来实现封包的功能。

常用方法:

方法名使用说明
DatagramPacket(byte[] buf, int length)构造数据报包,用来接收长度为 length 的数据包
DatagramPacket(byte[] buf, int length, InetAddress address, int port)构造数据报包,用来将长度为 length 的包发送到指定主机上的指定端口号
getAddress()获取发送或接收方计算机的IP地址,此数据报将要发往该机器或者是从该机器接收到的
getData()获取发送或接收的数据
setData(byte[] buf)设置发送的数据



3 DatagramSocket:用于发送或接收数据报包

当服务器要向客户端发送数据时,需要在服务器端产生一个DatagramSocket对象,在客户端产生一个DatagramSocket对象。服务器端的DatagramSocket将DatagramPacket发送到网络上,然后被客户端的DatagramSocket接收。

DatagramSocket有两种常用的构造函数。一种是无需任何参数的,常用于客户端;另一种需要指定端口,常用于服务器端。如下所示:

  1. DatagramSocket() :构造数据报套接字并将其绑定到本地主机上任何可用的端口。
  2. DatagramSocket(int port) :创建数据报套接字并将其绑定到本地主机上的指定端口。

常用方法:

方法名使用说明
send(DatagramPacket p)从此套接字发送数据报包
receive(DatagramPacket p)从此套接字接收数据报包
close()关闭此数据报套接字



4 UDP通信编程基本步骤:

  1. 创建客户端的DatagramSocket,创建时,定义客户端的监听端口。
  2. 创建服务器端的DatagramSocket,创建时,定义服务器端的监听端口。
  3. 在服务器端定义DatagramPacket对象,封装待发送的数据包。
  4. 客户端将数据报包发送出去。
  5. 服务器端接收数据报包。










2 创建服务端

(1 创建服务端接收数据的DatagramSocket对象——>使用完要关闭,用try-with-resource,给定服务端接收数据的端口)

(2 创建数据缓存区——>byte类型数组)

(3 创建数据报包对象——>给定2个参数——>缓冲区数组,缓冲区数组的长度)

(4 等待接收客户端所发送的数据——>datagramSocket.receive()😉

(5 取出数据——>getData();返回的是字节类型,转换成字符串类型,传长度时要传.getLength(),不能是数组的长度)







public class UDPServer {
  public static void main(String[] args) {
      
    //创建服务端接收数据的DatagramSocket对象
    try(DatagramSocket datagramSocket = new DatagramSocket(9999)){
      //创建数据缓存区
      byte[] b = new byte[1024];
      //创建数据报包对象
      DatagramPacket dp =new DatagramPacket(b,b.length);
      //等待接收客户端所发送的数据
      datagramSocket.receive(dp);
        
      //取数据  
      String str = new String(dp.getData(),0,dp.getLength());
      System.out.println(str);
     }catch(Exception e){
      e.printStackTrace();
     }
   }
}








3 创建客户端

(1 创建数据发送对象 DatagramSocket,需要指定消息的发送端口——>注意在本机上端口号不能一样

——>TCP通讯中服务端和客户端的端口是一个,UDP中是两个不同的端口,因为没有连接)

(2 消息需要进行类型转换,转换成字节数组数据类型——>把字符串转换成字节数组)

(3 创建数据报包装对象DatagramPacket——>给定4个参数——>数组,数组长度,new InetSocketAddress发送目标IP,端口)

(4 发送消息——>datagramSocket.send()😉







public class UDPClient {
  public static void main(String[] args) {
    //创建数据发送对象 DatagramSocket,需要指定消息的发送端口
    try(DatagramSocket ds = new DatagramSocket(8888)) {


      //消息需要进行类型转换,转换成字节数据类型。
      byte[] b = "嘉".getBytes();


      //创建数据报包装对象DatagramPacket
      DatagramPacket dp = new DatagramPacket(b, b.length, new InetSocketAddress("127.0.0.1", 9999));


      //发送消息
      ds.send(dp);
     }catch(Exception e){
      e.printStackTrace();
     }
   }
}











4 基本数据类型—创建服务端

(1 创建服务端接收数据的DatagramSocket对象)

(2 创建数据缓存区——>byte类型数组)

(3 创建数据报包对象——>给定2个参数——>缓冲区数组,缓冲区数组的长度)

(4 等待接收客户端所发送的数据——>datagramSocket.receive()😉

(5 接收基本类型数据——>使用数据流DataInputStream ——>ByteArrayInputStream可以直接从数组里读对象,然后把读到的信息打印出来)





public class BasicTypeUDPServer {
  public static void main(String[] args) {
      
    try(DatagramSocket datagramSocket = new DatagramSocket(9999)){
      byte[] buf = new byte[1024];
      DatagramPacket dp = new DatagramPacket(buf,buf.length);


      datagramSocket.receive(dp);
      
      //实现数据类型转换
      try(DataInputStream dis = new DataInputStream(new ByteArrayInputStream(dp.getData()))){
        //通过基本数据数据流对象获取传递的数据
        System.out.println(dis.readLong());
       }
     }catch(Exception e){
      e.printStackTrace();
     }
   }
}










v

5 基本数据类型—创建客户端

(1 创建DatagramSocket对象,给定端口)

(2 创建DataOutputStream和ByteArrayInputStream流对象)

(3 把一个基本数据类型通过数据流,写给了字节数组)

(4 将基本数据类型数据转换成字节数组类型)

(5 创建数据报包装对象DatagramPacket——>给定4个参数——>数组,数组长度,new InetSocketAddress发送目标IP,端口)

(6 发送消息——>datagramSocket.send()😉





public class BasicTypeClient {
  public static void main(String[] args) {
    long n = 2000L;
    try(DatagramSocket datagramSocket = new DatagramSocket(9000);
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      DataOutputStream dos = new DataOutputStream(bos)){


      dos.writeLong(n);
      //将基本数据类型数据转换成字节数组类型
      byte[] arr = bos.toByteArray();
      DatagramPacket dp = new DatagramPacket(arr,arr.length,new InetSocketAddress("127.0.0.1",9999));


      datagramSocket.send(dp);
     }catch (Exception e){
      e.printStackTrace();
     }
   }
}











6 对象类型—创建服务端

(当该对象需要在网络上传输时,一定要实现Serializable接口——>因为要用对象流来操作)

(服务端——>前面的都一样——>创建DatagramSocket对象,准备DatagramPacket(袋子),接收数据——>对接收的内容做类型转换ObjectInputStream和ByteArrayInputStream对象——>打印读到的数据)




创建Person类

/**
 * 当该对象需要在网络上传输时,一定要实现Serializable接口
 */
public class Person implements Serializable {
  private String name;
  private int age;
    
  public String getName() {
    return name;
   }
  public void setName(String name) {
    this.name = name;
   }
  public int getAge() {
    return age;
   }
  public void setAge(int age) {
    this.age = age;
   }
  @Override
  public String toString() {
    return "Person{" +
        "name='" + name + '\'' +
        ", age=" + age +
        '}';
   }
}

创建服务端

public class ObjectTypeServer {
  public static void main(String[] args) {
    try(DatagramSocket datagramSocket = new DatagramSocket(9999);){


      byte[] b = new byte[1024];
      DatagramPacket dp = new DatagramPacket(b,b.length);
      datagramSocket.receive(dp);


      //对接收的内容做类型转换
      try(ObjectInputStream objectInputStream = new ObjectInputStream(new ByteArrayInputStream(dp.getData()))){
        System.out.println(objectInputStream.readObject());
       }
     }catch(Exception e){
      e.printStackTrace();
     }
   }
}










7 对象类型—创建客户端

(创建DatagramSocket ,ByteArrayOutputStream ,ObjectOutputStream 对象)

(创建自定义对象,get,set方法——>然后把这个对象通过objectOutputStream写出去)

(将数据包装成DatagramPacket 对象——>给定4个参数)

(发送消息——>datagramSocket.send()😉







public class ObjectTypeClient {
  public static void main(String[] args) {
    try(DatagramSocket datagramSocket = new DatagramSocket(8888);
      ByteArrayOutputStream bos = new ByteArrayOutputStream();
      ObjectOutputStream oos = new ObjectOutputStream(bos)){


      Person p = new Person();
      p.setName("Oldlu");
      p.setAge(18);




      oos.writeObject(p);
      byte[] arr = bos.toByteArray();


      DatagramPacket dp = new DatagramPacket(arr,arr.length,new InetSocketAddress("127.0.0.1",9999));


      datagramSocket.send(dp);
     }catch(Exception e){
      e.printStackTrace();
     }
   }
}










8 网络编程总结

  • 端口是虚拟的概念,并不是说在主机上真的有若干个端口。

  • 在www上,每一信息资源都有统一且唯一的地址,该地址就叫URL(Uniform Resource Locator),它是www的统一资源定位符。

  • TCP与UDP的区别

    • TCP是面向连接的,传输数据安全,稳定,效率相对较低。
    • UDP是面向无连接的,传输数据不安全,效率较高。
  • Socket通信是一种基于TCP协议,建立稳定连接的点对点的通信。

  • 网络编程是由java.net包来提供网络功能。

    • InetAddress:封装计算机的IP地址和DNS(没有端口信息!)。
    • InetSocketAddress:包含IP和端口,常用于Socket通信。
    • URL:以使用它的各种方法来对URL对象进行分割、合并等处理。
  • 基于TCP协议的Socket编程和通信

    • “请求-响应”模式:
      • Socket类:发送TCP消息。
      • ServerSocket类:创建服务器。
  • UDP通讯的实现

    • DatagramSocket:用于发送或接收数据报包。
    • 常用方法:send()、receive()、 close()。
  • DatagramPacket:数据容器(封包)的作用

    • 常用方法:构造方法、getAddrress(获取发送或接收方计算机的IP地址)、getData(获取发送或接收的数据)、setData(设置发送的数据)。

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

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

相关文章

《Django 5 By Example》读后感

一、 为什么选择这本书? 本人的工作方向为Python Web方向,想了解下今年该方向有哪些新书出版,遂上packt出版社网站上看了看,发现这本书出版时间比较新(2024年9月),那就它了。 从2024年11月11日至2024年12月18日期间&…

基于Spring Boot的校园商城系统

一、系统背景与意义 随着互联网技术的快速发展,电子商务已经渗透到生活的方方面面。校园作为一个相对封闭但活跃的社群,同样需要一个专门的线上平台来满足其特殊的需求。基于Spring Boot的校园商城系统正是为此目的而设计,它结合了微服务架构…

感知机收敛性定理证明

1. 问题描述 感知机收敛性定理假设: 存在一个参数向量 θ(被归一化为单位向量,,以及一个正数 ,使得对所有训练样本 满足: 这是线性可分的假设,意味着每个样本点与正确超平面之间有一个至少为的…

ai绘图丨中国新年春节背景第二弹(附关键词

使用工具:千鹿AI 咒语:圆形平面讲台,5 个礼品盒和台灯交错排列,红色背景上的圆形,中国唐朝风格,红色和金色主题,3D 效果图,摄影棚灯光,简约产品展示模型,逼真…

深度学习每周学习总结J9(Inception V3 算法实战与解析 - 天气识别)

🍨 本文为🔗365天深度学习训练营 中的学习记录博客🍖 原作者:K同学啊 | 接辅导、项目定制 目录 0. 总结Inception V1 简介Inception V3 简介1. 设置GPU2. 导入数据及处理部分3. 划分数据集4. 模型构建部分5. 设置超参数&#xff1…

Restaurants WebAPI(一)—— clean architecture

文章目录 项目地址一、Restaurants.Domain 核心业务层1.1 Entities实体层1.2 Repositories 数据操作EF的接口二、Restaurants.Infrastructure 基础设施层2.1 Persistence 数据EF CORE配置2.2 Repositories 数据查询实现2.3 Extensions 服务注册三、Restaurants.Application用例…

道路运输企业安全生产管理人员安全考核试题

道路运输企业安全生产管理人员安全考核试题 一、单选题 题干:在公交车行驶过程中,乘客王某因与驾驶员发生矛盾,遂殴打驾驶员并抢夺方向盘,造成其他乘客受轻微伤,依照《中华人民共和国刑法》的规定,王某触…

FFmpeg库之ffplay

文章目录 FFmpeg环境搭建ffplay使用通用选项视频选项音频选项快捷键使用滤镜直播拉流 FFmpeg环境搭建 FFmpeg官网 FFmpeg环境搭建 ./configure \--prefix"$HOME/ffmpeg" \--extra-cflags"-I$HOME/ffmpeg/include" \--extra-ldflags"-L$HOME/ffmpeg…

HTTP 协议报文结构 | 返回状态码详解

注:本文为 “HTTP 历史 | 协议报文结构 | 返回状态码” 相关文章合辑。 未整理去重。 HTTP 历史 wangjunliang 最后更新: 2024/3/16 上午10:29 超文本传输协议(英语:HyperTextTransferProtocol,缩写:HTTP)是 万维网(World Wide Web)的基础协议。自 蒂姆…

springboot444新冠物资管理系统的设计与实现(论文+源码)_kaic

摘 要 传统办法管理信息首先需要花费的时间比较多,其次数据出错率比较高,而且对错误的数据进行更改也比较困难,最后,检索数据费事费力。因此,在计算机上安装新冠物资管理系统软件来发挥其高效地信息处理的作用&#x…

【数字信号处理】数字信号处理试题及答案,离散序列,Z变换,傅里叶变换

关注作者了解更多 我的其他CSDN专栏 过程控制系统 工程测试技术 虚拟仪器技术 可编程控制器 工业现场总线 数字图像处理 智能控制 传感器技术 嵌入式系统 复变函数与积分变换 单片机原理 线性代数 大学物理 热工与工程流体力学 数字信号处理 光电融合集成电路…

【系统】Mac crontab 无法退出编辑模式问题

【系统】Mac crontab 无法退出编辑模式问题 背景一、问题回答1.定位原因:2.确认编辑器类型3.确保编辑器进入正确3.1 确认是否有crontab调度任务3.2 进入编辑器并确保编辑器正常3.3 保存操作 4.确认crontab任务存在5.确保脚本的可执行性和正确性 二、后续 背景 之前…

6.3.1 MR实战:计算总分与平均分

在本次实战中,我们的目标是利用Apache Hadoop的MapReduce框架来处理和分析学生成绩数据。具体来说,我们将计算一个包含五名学生五门科目成绩的数据集的总分和平均分。这个过程包括在云主机上准备数据,将成绩数据存储为文本文件,并…

开发平台接口规范:北斗终端->客户平台(上行)| 时空信息产品

文章目录 引言I 技术架构和业务流程II 渠道接口验证签名白名单IP渠道配置表设计III 其他辅助功能TCP 发送消息到消息中心nginx转发网关服务异常捕获日志采集IV 知识扩展对请求参数进行校验引言 开发平台的应用场景:平台需要开发能力给下游平台需要接收上游的回调数据,例如接收…

MySQL知识汇总(一)

一些命令行操作注意加 分号 “ ; ” show databases 查看所有数据库 use 数据库名 切换数据库 show tables 查看数据库中所有表 describe 表名 显示表中所有信息 create database [if not exists] 新库名 创…

vsCode怎么使用vue指令快捷生成代码

1.下载Vetur插件 2.在文件-首选项-配置代码片段中找到vue.json文件 (注:旧版本的编辑器路径为文件-首选项-用户片段) 3.在打开的配置代码片段弹窗中搜索vue.json,找到并打开 (注:如果搜不到的话就按住鼠标…

QAnything源码学习

以下解读基于时间:20241218 概述 官方架构图如下: 该有的模块基本上都有了: Query理解检索 召回重排 大模型生成数据入库 下面就从以上几个模块分别看看对应的源码 讲源码之前还是想先讲讲这个项目的目录结构,这样可能会更方…

【LeetCode】每日一题 2024_12_19 找到稳定山的下标(模拟)

前言 每天和你一起刷 LeetCode 每日一题~ 最近力扣的每日一题出的比较烂,难度过山车,导致近期的更新都三天打鱼,两天断更了 . . . LeetCode 启动! 题目:找到稳定山的下标 代码与解题思路 先读题:最重要…

Android笔记【19】

具体示例 run: val result someObject.run {// 这里可以使用 thisthis.someMethod() }let: val result someObject?.let {// 这里使用 itit.someMethod() }with: val result with(someObject) {// 这里使用 thissomeMethod() }apply: val obj SomeClass().apply {// 这里使…

【一篇搞定配置】如何在Ubuntu上配置单机/伪分布式Hadoop

🌈 个人主页:十二月的猫-CSDN博客 🔥 系列专栏: 🏀各种软件安装与配置_十二月的猫的博客-CSDN博客 💪🏻 十二月的寒冬阻挡不了春天的脚步,十二点的黑夜遮蔽不住黎明的曙光 目录 1.…