zoukankan      html  css  js  c++  java
  • 网络编程之UDP

    什么是UDP通信

    面向无连接、不可靠、速度快、将数据封装成包传输,数据包最大64k

    UPD通信的过程就像是货运公司在两个码头之间发送货物一样,在码头发送和接收货物时都需要使用集装箱来装载货物。UPD通信也一样,发送和接收的数据也需要使用 " 集装箱 " 进行打包,为此JDK中提供了一个DatagramPacket类,该类的实例对象就相当于一个集装箱,用于封装UPD通信中发送或者接收的数据。

    DatagramPacket(byte[] buf,int length)

    使用该构造方法在创建DatagramPacket对象时,指定了封装数据的字节数组和数据的大小,没有指定IP地址和端口号。很明显,这样的对象只能用于接收端,不能用于发送端。因为发送端一定要明确指出数据的目的地(IP地址和端口号),而接收端不需要明确知道数据的来源,只需要接收到数据即可。

    DatagramPacket(byte[] buf,int length,InetAddress address,int port)

    使用该构造方法在创建DatagramPacket对象时,不仅指定了封装数据的字节数组和数据的大小,还指定了数据包的目标IP地址(addr)和端口号(port)。该对象通常用于发送端,因为在发送数据时必须指定接收端的IP地址和端口号,就好像发送货物的集装箱上面必须标明接收人的地址一样。

    上面讲到DatagramPacket数据包的作用就如同 " 集装箱 ",可以将发送端或者接收端的数据封装起来。然而运输货物只有 " 集装箱 " 是不够的,还需要 " 码头 "。同理,在程序中,要实现通信,只有DatagramPacket数据包也是不行的,它也需要一个 " 码头 "。为此,JDK提供了一个DatagramSocket类,该类的作用就类似于 " 码头 ",使用这个类的实例对象就可以发送和接收DatagramPacket的数据包。

    DatagramSocket(int port)

    该构造方法即可用于创建接收端的DatagramSocket对象,又可以创建发送端的DatagramSocket对象,在创建接收端的DatagramSocket对象时,必须要指定一个端口号,这样就可以监听指定的端口。

     UDP网络程序

    上面讲解了DatagramPacket和DatagramSocket的相关知识,接下来通过一个案例来学习一下他们在程序中的具体用法。要实现UDP通信需要创建一个发送端程序和一个接收端程序,很明显,在通信时只有接收端程序先运行,才能避免发送端发送数据时找不到接收端而造成的数据丢失问题。

    建立UDP主机A(接收方)编程模型:

      1. 创建DatagramSocket类型的对象,并提供端口号
      2. 创建DatagramPacket类型的对象,用于接收发送来的数据
      3. 使用上述对象接收数据的内容,使用recieve()方法
      4. 关闭相关资源

    public class Example01 {
        public static void main(String[] args) throws Exception {
            //创建一个长度为1024的字节数组,用于放数据
            byte[] by = new byte[1024];
            //定义一个DatagramSocket对象,监听的端口号为8899;
            DatagramSocket ds = new DatagramSocket(8899);
            //定义一个DatagramPacket对象,用于接收数据
            DatagramPacket dp = new DatagramPacket(by, by.length);
            //等待接收数据,没有数组则会阻塞
            ds.receive(dp);
            //获取接收到的数据,包括数据内容、长度、发送端和IP地址和端口号
            String str = new String(dp.getData(),0,dp.getLength()) + " from "+dp.getAddress().getHostAddress()+":"+dp.getPort();
            System.out.println(str);     //打印接收到的信息
            //关闭资源
            ds.close();
        }
    }

    运行接收端程序后,程序一直处于停滞状态,这是因为DatagramSocket的receive()方法在运行时会发生阻塞,只有接收到发送端程序发送的数据时,该方法才会结束这种阻塞状态,程序才会继续向下执行。

    建立UDP主机B(发送方)编程模型:

      1. 创建DatagramSocket类型的对象
      2. 创建DatagramPacket类型的对象,并提供端口号和IP地址
      3. 使用上述的对象发送数据内容,使用send()方法
      4. 关闭相关资源

    public class Example02 {
        public static void main(String[] args) throws Exception {
            //创建一个DatagramSocket对象,指定本地端口号
            DatagramSocket ds = new DatagramSocket(8520);
            //要发送的数据
            byte[] str="嘿嘿嘿".getBytes();
            //创建一个要发送的数据,指定数据、IP地址、端口号
            DatagramPacket dp = new DatagramPacket(str, str.length, InetAddress.getByName("localhost"), 8899);
            System.out.println("发送数据!");
            //发送数据
            ds.send(dp);
            //关闭资源
            ds.close();
        }
    }

    在接收端程序阻塞的状态下,运行发送端程序,接收端程序就会收到发送端发送的数据而结束阻塞状态,并打印接收到的数据。

    需要注意的是,在创建发送端的DatagramSocket对象时,可以不指定端口号,程序中指定端口号的目的是为了每次运行时接收端的getPort()方法的返回值都是一直的,否则发送端的端口号由系统自动分配,接收端的getPort()方法的返回值每次都不同。

    学习中,博客都是自己学习用的笔记,持续更新改正。。。
  • 相关阅读:
    四,awk格式化
    printf命令详解
    三,awk变量
    二,awk分隔符
    一,AWK基础
    【leetcode_easy_array】1399. Count Largest Group
    【leetcode_easy_array】1184. Distance Between Bus Stops
    【leetcode_easy_array】1346. Check If N and Its Double Exist
    【leetcode_easy_array】1304. Find N Unique Integers Sum up to Zero
    【leetcode_easy_array】1337. The K Weakest Rows in a Matrix
  • 原文地址:https://www.cnblogs.com/Tunan-Ki/p/11681140.html
Copyright © 2011-2022 走看看