Java—UDP通信,DatagramPacket和DatagramSocket

DatagramPacket

DatagramPacket:UDP数据传输的数据包,接收或者发送的数据都是通过这个进行包装

常用构造方法

  1. public DatagramPacket(byte buf[], int offset, int length)

    buf:传入一个空字节数组用来存储数据
    offset:偏移量,字节数组开始存储的位置
    length:允许存储的最大长度

    适用于:接受数据(特征:没有指定地址,数组是空的)

    衍生类似的构造方法,如:

    public DatagramPacket(byte buf[], int length) {
            this (buf, 0, length);
        }
    
  2. public DatagramPacket(byte buf[], int offset, int length, InetAddress address, int port)

    buf:要传输数据的字节数组形式,跟前面不一样的是非空字节数组
    offset:偏移量,字节数组开始传输的位置
    length:传输的最大长度
    address:要发送的对象的ip地址
    port:要发送对象的端口号

    适用于:发送数据(特征:存在指定地址,数组有值的)

    衍生类似的构造方法,如:

    public DatagramPacket(byte buf[], int offset, int length, SocketAddress address) {
            setData(buf, offset, length);
            setSocketAddress(address);
        }
    

DatagramSocket

在Java中使用DatagramSocket表示UDP的Socket,不同于TCP的Socket,他不能产生流;在UDP传输过程中只是起到一个“交换器”作用,负责接受数据和发送数据(数据形式都是DatagramPacket)

常用构造方法

  1. public DatagramSocket()

    空参构造方法,默认会将该Socket绑定本机ip和随机一个可用端口上
    不推荐使用,尤其是作为服务器准备接收数据的一方,必须要指定端口,只有这样才能确保客户端的信息能够到达

  2. public DatagramSocket(int port)

    指定端口,默认会将该Socket绑定本机ip

  3. public DatagramSocket(int port, InetAddress laddr)

    指定ip、指定端口

常用方法

  1. receive(DatagramPacket p)

    · 结合DatagramPacket对象接收数据,并将数据存到DatagramPacket中的空数组中,而且之后可以 通过这个DatagramPacket对象拿到发送端的ip、端口等信息。
    · 阻塞,直到有信息发送过来被接受

  2. send(DatagramPacket p)

    发送数据。DatagramSocket只负责发送数据,具体的接收方信息(ip、端口)都是DatagramPacket携带的

Demo

接收方

package day20200328;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;

/**
 * @Author: xiaoshijiu
 * @Date: 2020/3/28
 * @Description: UDP:无连接的通信方式,即不能通过流的形式传输数据
 * DatagramPacket:UDP数据传输的数据包,接收或者发送的数据都是通过这个进行包装
 * DatagramSocket:UDP数据传输"交换机",负责接受数据或者将数据传输出去
 */
public class UDPReceive {

    public static void main(String[] args) {

        DatagramSocket socket = null;

        try {
            byte[] buf = new byte[1024];
            // 这个构造方法,指将接收到的数据存入到buf中,最多能存的长度是buf.length
            DatagramPacket packet_receive = new DatagramPacket(buf, buf.length);
            // 创建了一个指定端口为5555的UDP传输器Socket(ip即本机默认ip)
            socket = new DatagramSocket(5555);
            // 该方法会阻塞,直至有信息到达
            socket.receive(packet_receive);
            System.out.println("接收到的数据为:" + new String(buf, 0, buf.length));

            byte[] mes = "这是我给你的反馈信息...".getBytes();
            // 这个构造方法:buf并不是空数组,代表有具体的内容需要发出去,而且需要指定发送的具体的地址和端口
            System.out.printf("%s,%d\n", packet_receive.getAddress().getHostAddress(), packet_receive.getPort());
            DatagramPacket packet_send = new DatagramPacket(mes, mes.length, packet_receive.getAddress(), packet_receive.getPort());
            socket.send(packet_send);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // UDP传输只需要关闭 "交换机"Socket
            if (socket != null) {
                socket.close();
            }
        }
    }

}

发送方

package day20200328;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetSocketAddress;

/**
 * @Author: xiaoshijiu
 * @Date: 2020/3/28
 * @Description: UDP:无连接的通信方式,即不能通过流的形式传输数据
 * DatagramPacket:UDP数据传输的数据包,接收或者发送的数据都是通过这个进行包装
 * DatagramSocket:UDP数据传输"交换机",负责接受数据或者将数据传输出去
 */
public class UDPSend {

    public static void main(String[] args) {

        DatagramSocket socket = null;
        try {
            byte[] mes = "xiaoguo,xiaoguo,fuqiduoduo".getBytes();

            // 发送数据,数据包必须要包含该数据待发送的地址(ip+端口)
            DatagramPacket packet_send = new DatagramPacket(mes, mes.length, new InetSocketAddress("127.0.0.1", 5555));

            // 如果只发送数据可以不用申明具体的端口,系统会随机一个可用的端口;如果接受数据的话,最好要最先定义好属于自己的一个端口
            socket = new DatagramSocket(5556);
            socket.send(packet_send);

            byte[] buf = new byte[1024];
            // 这个构造方法,指将接收到的数据存入到buf中,最多能存的长度是buf.length
            DatagramPacket packet_receive = new DatagramPacket(buf, buf.length);
            socket.receive(packet_receive);
            System.out.println("接收到的反馈信息是:" + new String(buf, 0, buf.length));
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // UDP传输只需要关闭 "交换机"Socket
            if (socket != null) {
                socket.close();
            }
        }

    }


}

先启动UDPReceive ,再启动UDPSend
运行结果
Java—UDP通信,DatagramPacket和DatagramSocket_第1张图片
Java—UDP通信,DatagramPacket和DatagramSocket_第2张图片

你可能感兴趣的:(JAVA-IO)