JAVA深化篇_38—— UDP通信的实现和项目案例

news/2024/5/18 12:07:42 标签: java, udp, 网络

UDP通信的实现和项目案例

UDP通信实现原理

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

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

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

常用方法:

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

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

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

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

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

常用方法:

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

UDP通信编程基本步骤:

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

UDP通信入门案例

创建服务端

java">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();
     }
   }
}

创建客户端

java">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();
     }
   }
}

UDP协议传递基本数据类型

创建服务端

java">public class BasicDataUDPServer {
    public static void main(String[] args) {

        try(DatagramSocket datagramSocket =new DatagramSocket(9999);){
            //创建字节数组缓冲区
            byte[] bytes = new byte[1024];
            //创建datagramPacket存放字节数组类型的数据
            DatagramPacket datagramPacket=new DatagramPacket(bytes,bytes.length);
            //等待客户端传入数据
            datagramSocket.receive(datagramPacket);
            //实现数据类型转换
            try(DataInputStream dataInputStream =new DataInputStream(new ByteArrayInputStream(bytes))){
                //通过基本数据数据流对象获取传递的数据
                System.out.println(dataInputStream.readLong());
            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

创建客户端

java">public class BasicDataUDPClient {
    public static void main(String[] args) {
        //创建发送数据的DatagramSocket对象
        try(DatagramSocket datagramSocket = new DatagramSocket(8856);
            //创建将基本数据类型转换为字节数组的ByteArrayOutputStream对象
            ByteArrayOutputStream byteArrayOutputStream=new ByteArrayOutputStream();
            //创建将基本数据类型写入ByteArrayOutputStream中的数据输出流对象
            DataOutputStream dataOutputStream =new DataOutputStream(byteArrayOutputStream)){
            //要传递的数据
            long data=10000l;
            //写入ByteArrayOutputStream对象
            dataOutputStream.writeLong(data);
            //将基本数据类型转换为字节数组
            byte[] byteArray = byteArrayOutputStream.toByteArray();
            //将字节数组包装到 DatagramPacket中
            DatagramPacket datagramPacket=new DatagramPacket(byteArray,byteArray.length
            , new InetSocketAddress("127.0.0.1",9999));
            //发送数据
            datagramSocket.send(datagramPacket);

        }catch (Exception e){
            e.printStackTrace();
        }
    }
}


传递自定义对象类型

创建Person类

java">/**
 * 当该对象需要在网络上传输时,一定要实现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 +
        '}';
   }
}

创建服务端

java">public class Person {
    public static void main(String[] args) {
        try(DatagramSocket datagramSocket =new DatagramSocket(9999);){

            byte[] bytes =new byte[1024];

            DatagramPacket datagramPacket =new DatagramPacket(bytes,bytes.length);
            //接收数据
            datagramSocket.receive(datagramPacket);

            //数据类型转换
            try (ObjectInputStream ois = new ObjectInputStream(
                    new ByteArrayInputStream(datagramPacket.getData()))){
                Person person = (Person)ois.readObject();
                System.out.println(person);

            }
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}

创建客户端

java">public class ObjectTypeClient {
    public static void main(String[] args) {
        try(DatagramSocket datagramSocket =new DatagramSocket();
            ByteArrayOutputStream bos =new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(bos)){
            //实例化Person对象
            Person person =new Person();
            person.setAge(18);
            person.setName("zhangsan");
             //写入ByteArrayOutputStream对象
            oos.writeObject(person);
            //将自定义数据类型转换为字节数组类型
            byte[] byteArray = bos.toByteArray();
            //将自定义数据类型包装到DatagramPacket中
            DatagramPacket datagramPacket=new DatagramPacket(byteArray,byteArray.length,
                                                 new InetSocketAddress("127.0.0.1",9999));
            //发送数据
            datagramSocket.send(datagramPacket);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
}



http://www.niftyadmin.cn/n/5173003.html

相关文章

NetApp Ontap 9 版本下的磁盘管理命令汇总

NetApp Ontap 9 相比以前的7-mode版本架构有了很大的不同,命令也对应发生了很多的变化,这里把ontap 9下对磁盘管理的一些常用命令进行了汇总,供朋友们在维护磁盘时候检查使用。也欢迎一起探讨,add wechat at StorageExpert。 功能…

深入理解 Django 单元测试

在现代软件开发流程中,单元测试是确保代码质量和可维护性的关键组成部分。对于使用 Django 框架的项目来说,Django 提供了一套强大的测试工具来帮助开发者编写和运行单元测试。本文将深入探讨 Django 中的单元测试,包括测试原理、编写测试用例…

免费分享一套基于Springboot+Vue的在线考试系统,挺漂亮的

大家好,我是java1234_小锋老师,看到一个不错的SpringbootVue的在线考试系统,分享下哈。 项目视频演示 【免费】springbootvue在线考试系统 Java毕业设计_哔哩哔哩_bilibili【免费】springbootvue在线考试系统 Java毕业设计项目来自互联网&a…

Pathways

信号通路signaling pathway-武汉华美生物 (cusabio.cn) 神经信号通路(Neuronal Signaling)--selleck.cn PI3K/Akt/mTOR信号通路 表观遗传 甲基化 免疫&炎症 酪氨酸蛋白激酶 血管生成 凋亡 自噬 内质网应激&UPR响应 JAK/STAT信号通路 MAPK信号通路 细胞骨架…

使用米联客FPGA开发板进行光口开发时遇到的问题总结

使用的开发板型号:米联客MA703FA, 实物图如下 FPGA型号为a35t 米联客提供的开发板资料中的FPGA型号为a100,所以要想使用开发板例程必须进行FPGA的重新选择。如下图 通过对开发板原理图的分析,例程代码不用做任何修改就可使用&am…

如何在 Azure 中使用自动机器学习进行模型训练

自动机器学习(Automated Machine Learning,简称为AutoML)是一种通过自动化流程来简化模型训练和调优的技术。在Azure机器学习平台中,AutoML提供了丰富的功能和工具,使我们能够快速地训练和优化机器学习模型。本文将介绍…

redux-devtools谷歌扩展插件的使用示例

目录 1. store.ts 2. reducer.ts 3. ReduxProvider.tsx 4. mapStateToProps.ts 5. mapDispatchToProps.ts 6. Todo组件(最外层包ReduxProvider 7. Todo组件里面涉及的子组件 1) TodoInput.tsx 2) TodoList.tsx 3) TodoItem.tsx 8. App组件使用Todo组件 1. store.ts …

PHP代码示例

我们需要使用PHP的curl库来发送HTTP请求。以下是一个基本的示例&#xff1a; php <?php // 初始化curl $ch curl_init(); // 设置代理 curl_setopt($ch, CURLOPT_PROXY, ""); // 设置URL curl_setopt($ch, CURLOPT_URL, ""); // 执行请求 $respon…