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
運行結果
在這裏插入圖片描述
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章