专栏首页Java研发军团初学者第69节网络编程-UDP

初学者第69节网络编程-UDP

引言

UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连接的传输层协议,提供面向事务的简单不可靠信息传送服务,IETF RFC 768是UDP的正式规范。UDP在IP报文的协议号是17。

在选择使用协议的时候,选择UDP必须要谨慎。在网络质量令人十分不满意的环境下,UDP协议数据包丢失会比较严重。但是由于UDP的特性:它不属于连接型协议,因而具有资源消耗小,处理速度快的优点,所以通常音频、视频和普通数据在传送时使用UDP较多,因为它们即使偶尔丢失一两个数据包,也不会对接收结果产生太大影响。比如我们聊天用的ICQ和QQ就是使用的UDP协议

以上都是百度百科解释

总结一句:UDP 是用户数据报协议的缩写,一个无连接的协议。提供了应用程序之间要发送的数据的数据包。

UDP应用场景主要有

(1)面向数据报方式;

(2)网络数据大多为短消息;

(3)拥有大量Client;

(4)对数据安全性无特殊要求;

(5)网络负担非常重,但对响应速度要求高。

UDP网络编程简单使用

udp的服务端的编写步骤

  1. 创建DatagramSocket类的套接字,并且设置服务端的端口
  2. 创建接收客户端传过来的书籍的容器
  3. 使用DatagramPacket将容器打包
  4. 接收数据
  5. 分析数据
  6. 关闭资源

udp的客户端的编写步骤

  1. 创建DatagramSocket类的套接字,并且设置客户端的端口
  2. 准备要发送的数据以byte[]格式
  3. 使用DatagramPacket将数据打包
  4. 发送数据
  5. 关闭资源

下面我们编写一个字符串传输和一个list数组传输的例子吧

udp字符串传输例子

按照上面udp的服务端和客户端的步骤编写字符串传输的例子

服务端代码

public class UDPServer {
    public static void main(String[] args) throws IOException {
        /**
         udp的服务端的编写步骤
         1.创建DatagramSocket类的套接字,并且设置服务端的端口
         2.创建接收客户端传过来的书籍的容器
         3.使用DatagramPacket将容器打包
         4.接收数据
         5.分析数据
         6.关闭资源
         */
        //创建DatagramSocket类的套接字,并且设置服务端的端口
        DatagramSocket server = new DatagramSocket(10000);
        //创建接收客户端传过来的书籍的容器
        byte[] bytes = new byte[1024];
        //使用DatagramPacket将容器打包
        DatagramPacket packet = new DatagramPacket(bytes,bytes.length);
        //接收数据
        server.receive(packet);
        //分析数据
        byte[] data = packet.getData();
        int len = packet.getLength();
        server.close();
        System.out.println(new String(data,0,len));

    }
}

客户端代码

public class UDPClient {
    public static void main(String[] args) throws IOException {
        /**
         udp的客户端的编写步骤
         1.创建DatagramSocket类的套接字,并且设置客户端的端口
         2.准备要发送的数据以byte[]格式
         3.使用DatagramPacket将数据打包
         4.发送数据
         5.关闭资源
         */
        //创建DatagramSocket类的套接字,并且设置客户端的端口
        DatagramSocket client = new DatagramSocket(20000);
        //准备要发送的数据以byte[]格式
        byte[] data = "我是client".getBytes();
        //使用DatagramPacket将数据打包
        DatagramPacket packet = new DatagramPacket(
                data,data.length, InetAddress.getLocalHost(),//本地ip
                10000 //服务器的端口
        );
        //发送数据
        client.send(packet);
        //关闭资源
        client.close();
    }
}

输出结果:
我是client

这就是最简单的udp传输的例子

udp对象传输例子

对象传输只需要将传输的字符串改成对象即可,这里我们使用list集合吧!

由于网络传输都是使用byte[],所以这个时候我们需要新增一个将list集合转成byte[]数组的方法。在改造当中需要使用到io当中的4个类

ByteArrayOutputStream、ByteArrayInputStream

ObjectOutputStream、ObjectInputStream

注意使用ObjectOutputStream、ObjectInputStream2个类一定要将类序列化就是要继承

Serializable 接口

客户端改造

1、创建一个Car类属性有名称和价格

2、在UDPClient类中增加一个setData方法,返回值为byte[]

Car类代码

public class Car implements Serializable {
    private String name;
    private double price;

    public Car(String name, double price) {
        this.name = name;
        this.price = price;
    }
    @Override
    public String toString() {
        return "Car{" +
                "name='" + name + '\'' +
                ", price=" + price +
                '}'+"\r\n";
    }
}

setData方法代码

private static byte[] setData() throws IOException {
    List<Car> carList = new ArrayList<>();
    carList.add(new Car("奔驰",10000.00));
    carList.add(new Car("宝马",20000.00));
    carList.add(new Car("凯迪拉克",30000.00));
    carList.add(new Car("雷克萨斯",40000.00));
    //使用io中的ByteArrayOutputStream,ObjectOutputStream,将list集合转换为byte数组
    ByteArrayOutputStream outByteArray = new ByteArrayOutputStream();
    ObjectOutputStream out = new ObjectOutputStream(outByteArray);
    out.writeObject(carList);
    byte[] bytes = outByteArray.toByteArray();
    out.close();
    outByteArray.close();
    return bytes;
}

服务端改造

在UDPServer类中增加一个getData方法,返回值为List集合

private static List<Car> getData(byte[] data,int len) throws IOException, ClassNotFoundException {
    ByteArrayInputStream inByteArray = new ByteArrayInputStream(data,0,len);
    ObjectInputStream in = new ObjectInputStream(inByteArray);
    List<Car> carList = (List<Car>) in.readObject();
    in.close();
    inByteArray.close();
    return carList;
}

输出结果:
[Car{name='奔驰', price=10000.0}
, Car{name='宝马', price=20000.0}
, Car{name='凯迪拉克', price=30000.0}
, Car{name='雷克萨斯', price=40000.0}
]

以上2个小例子写完了,主要是在实际应用场景中灵活运用了

本文分享自微信公众号 - Java研发军团(ityuancheng),作者:猿程之家

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2018-05-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 阅读源码的利器 — Intellij IDEA中 Replace in Path 的使用技巧

    2、Preserve case: 如果勾选该按钮,搜索时不区分大小写,但替换的时候,将会把你给定的字符串的首字母替换成小写。

    用户5224393
  • Java性能优化的50个细节,我必须分享给你!

    来源:blog.csdn.net/dongnan591172113/article/details/51790428

    用户5224393
  • 初学者第70节网络编程-Socket(一)

    java.net 包中 J2SE 的 API 包含有类和接口,它们提供低层次的通信细节。你可以直接使用这些类和接口,来专注于解决问题,而不用关注通信细节。

    用户5224393
  • 第二十期技术雷达正式发布——给你有态度的技术解析!

    技术雷达是ThoughtWorks每半年发布一期的技术趋势报告,它不仅是一份持续的技术成熟度评估,其产生还源于ThoughtWorks另一个更大宏大的使命—IT...

    ThoughtWorks
  • Smart template的控件能否当成普通控件来用

    只要弄清楚Smart control的原理,就能回答这个问题。

    Jerry Wang
  • tensorflow ‘/biases/Adam_1’not in ckpt file

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_25737169/article/d...

    DoubleV
  • 如何在 Windows 上安装ONLYOFFICE组织您的团队合作

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/det...

    hotqin888
  • ONLYOFFICE 开发相关 总结

    版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/hotqin888/article/det...

    hotqin888
  • 史上首个人脸识别禁令出台,警察用来抓罪犯也不行!旧金山可真行

    禁令是旧金山监事会(Board of Supervisors)今天刚刚通过的。监事会是一个专门监督旧金山政府的机构,有立法权,类似本地的议会,由旧金山每个区的民...

    量子位
  • LVM的创建、扩展、收缩及快照功能的介绍

    LVM是在物理卷(Physical Volume)上再建立了一层逻辑层。可以将多块磁盘组成卷组,再划分为多个逻辑卷。

    二狗不要跑

扫码关注云+社区

领取腾讯云代金券