C語言中文網 目錄

Java UDP通信:Java DatagramSocket類和DatagramPacket類

在 TCP/IP 協議的傳輸層除了一個 TCP 協議之外,還有一個 UDP 協議。UDP 協議是用戶數據報協議的簡稱,也用于網絡數據的傳輸。雖然 UDP 協議是一種不太可靠的協議,但有時在需要較快地接收數據并且可以忍受較小錯誤的情況下,UDP 就會表現出更大的優勢。

下面是在 Java 中使用 UDP 協議發送數據的步驟。
  1. 使用 DatagramSocket() 創建一個數據包套接字。
  2. 使用 DatagramPacket() 創建要發送的數據包。
  3. 使用 DatagramSocket 類的 send() 方法發送數據包。

接收 UDP 數據包的步驟如下:
  • 使用 DatagramSocket 創建數據包套接字,并將其綁定到指定的端口。
  • 使用 DatagramPacket 創建字節數組來接收數據包。
  • 使用 DatagramPacket 類的 receive() 方法接收 UDP 包。

DatagramPacket 類

java.net 包中的 DatagramPacket 類用來表示數據報包,數據報包用來實現無連接包投遞服務。每條報文僅根據該包中包含的信息從一臺機器路由到另一臺機器。從一臺機器發送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。表 1 和表 2 簡單介紹了 DatagramPacket 的構造方法和常用方法。

表1 DatagramPacket的構造方法
構造方法 說明
DatagramPacket(byte[] buf,int length) 構造 DatagramPacket,用來接收長度為 length 的數據包。
DatagramPacket(byte[] buf,int offset,
int length)
構造 DatagramPacket,用來接收長度為 length 的包,在緩
沖區中指定了偏移量。
DatagramPacket(byte[] buf,int length,
InetAddress address,int port)
構造 DatagramPacket,用來將長度為 length 的包發送到指
定主機上的指定端口。
DatagramPacket(byte[] buf,int length,
SocketAddress address)
構造數據報包,用來將長度為 length 的包發送到指定主機上
的指定端口。
DatagramPacket(byte[] buf,int offset,
int length,InetAddress address,int port)
構造 DatagramPacket,用來將長度為 length 偏移量為 offset
的包發送到指定主機上的指定端口。
DatagramPacket(byte[] buf,int offset,
int length,SocketAddress address)
構造數據報包,用來將長度為 length、偏移量為 offset 的包發
送到指定主機上的指定端口。

表2 DatagramPacket的常用方法
方法 說明
InetAddress getAddress() 返回某臺機器的 IP 地址,此數據報將要發往該機器或者
從該機器接收。
byte[] getData() 返回數據緩沖區。
int getLength() 返回將要發送或者接收的數據的長度。
int getOffset() 返回將要發送或者接收的數據的偏移量。
int getPort() 返回某臺遠程主機的端口號,此數據報將要發往該主機或
者從該主機接收。
getSocketAddress() 獲取要將此包發送或者發出此數據報的遠程主機的
SocketAddress(通常為 IP地址+端口號)。
void setAddress(InetAddress addr) 設置要將此數據報發往的目的機器的IP地址。
void setData(byte[] buf) 為此包設置數據緩沖區。
void setData(byte[] buf,int offset,
int length)
為此包設置數據緩沖區。
void setLength(int length) 為此包設置長度。
void setPort(int port) 設置要將此數據報發往的遠程主機的端口號。
void setSocketAddress(SocketAddress
address)
設置要將此數據報發往的遠程主機的
SocketAddress(通常為 IP地址+端口號)。

DatagramSocket 類

DatagramSocket 類用于表示發送和接收數據報包的套接字。數據報包套接字是包投遞服務的發送或接收點。每個在數據報包套接字上發送或接收的包都是單獨編址和路由的。從一臺機器發送到另一臺機器的多個包可能選擇不同的路由,也可能按不同的順序到達。

DatagramSocket 類的常用構造方法如表 3 所示。

表3 DatagramSocket 的構造方法
構造方法 說明
DatagramSocket() 構造數據報包套接字并將其綁定到本地主機上任何可用的端口。
DatagramSocket(int port) 創建數據報包套接字并將其綁定到本地主機上的指定端口。
DatagramSocket(int portJnetAddress addr) 創建數據報包套接字,將其綁定到指定的本地地址。
DatagramSocket(SocketAddress bindaddr) 創建數據報包套接字,將其綁定到指定的本地套接字地址。

DatagramSocket 類的常用方法如表 4 所示。

表4 DatagramSocket 的常用方法
方法 說明
void bind(SocketAddress addr) 將此 DatagramSocket 綁定到特定的地址和端口。
void close() 關閉此數據報包套接字。
void connect(InetAddress address,int port) 將套接字連接到此套接字的遠程地址。
void connect(SocketAddress addr) 將此套接子連接到遠程套接子地址(IP地址+端口號)。
void disconnect() 斷開套接字的連接。
InetAddress getInetAddress() 返回此套接字連接的地址。
InetAddress getLocalAddress() 獲取套接字綁定的本地地址。
int getLocalPort() 返回此套接字綁定的本地主機上的端口號。
int getPort() 返回此套接字的端口。

例 1

編寫 UDP 程序,要求客戶端程序可以向服務器端發送多條數據,服務器端程序可以接收客戶端發送的多條數據并將其信息輸出在控制臺,主要步驟如下所示。

(1) 創建一個類作為客戶端,在 main() 方法定義一個 DatagramSocket 對象和一個 DatagramPacket 對象并初始化為 null。然后再定義一個 InetAddress 對象和一個端口號并分別進行初始化,代碼如下所示。
public static void main(String[] args)
{
    DatagramSocket ds=null;
    DatagramPacket dpSend=null;
    InetAddress ia=InetAddress.getByName("127.0.0.1");
    int port=3021;
}

(2) 使用 DatagramSocket 的 send(DatagramPacket p) 方法向服務器端發送數據報包,使用循環的方式完成 5 次數據的發送,每發送 1 次數據線程休眠 1000 毫秒,數據發送完畢調用 close() 方法,關閉 DatagramSocket 對象,代碼如下。
try
{
    ds=new DatagramSocket();
    for(int i=0;i<5;i++)
    {
        byte[] data=("我是 UDP 客戶端"+i).getBytes();
        dpSend=new DatagramPacket(data,data.length,ia,port);
        ds.send(dpSend);
        Thread.sleep(1000);
    }
    ds.close();
}
catch(IOException | InterruptedException e)
{
    // TODO 自動生成的 catch 塊
    e.printStackTrace();
}   

(3) 創建一個類作為服務器端,在 main() 方法中定義一個 DatagramSocket 對象和一個 DatagramPacket 對象并初始化為 null,再定義一個端口號,代碼如下所示。
public static void main(String[] args)
{
    DatagramSocket ds=null;
    DatagramPacket dpReceive=null;
    int port=3021;
}

(4) 如果成功連接到 UDP 服務器則輸出“UDP 服務器已啟動。。。”。循環接收客戶端發送的數據,并將其發送的內容以及IP地址等信息輸出到控制臺,代碼如下所示。
try
{
    ds=new DatagramSocket(port);
    System.out.println("UDP服務器已啟動。。。");
    byte[] b=new byte[1024];
    while(ds.isClosed()==false)
    {
        dpReceive=new DatagramPacket(b, b.length);
        try
        {
            ds.receive(dpReceive);
            byte[] Data=dpReceive.getData();
            int len=Data.length;
            System.out.println("UDP客戶端發送的內容是:" + new String(Data, 0, len).trim());
            System.out.println("UDP客戶端IP:" + dpReceive.getAddress());
            System.out.println("UDP客戶端端口:" + dpReceive.getPort());
        }
        catch(IOException e)
        {
            e.printStackTrace();
        }
    }
    }
    catch(SocketException e1)
    {
        // TODO 自動生成的 catch 塊
        e1.printStackTrace();
    }
}

(5) 最后關閉 DatagramSocket 對象。執行服務器端程序,運行結果如下所示。
UDP服務器已啟動。。。

(6) 再運行客戶端程序,控制臺的輸出結果如下所示。
UDP客戶端發送的內容是:我是UDP客戶端0
UDP客戶端IP:/127.0.0.1
UDP客戶端端口:53472
UDP客戶端發送的內容是:我是UDP客戶端1
UDP客戶端IP:/127.0.0.1
UDP客戶端端口:53472
UDP客戶端發送的內容是:我是UDP客戶端2
UDP客戶端IP:/127.0.0.1
UDP客戶端端口:53472
UDP客戶端發送的內容是:我是UDP客戶端3
UDP客戶端IP:/127.0.0.1
UDP客戶端端口:53472
UDP客戶端發送的內容是:我是UDP客戶端4
UDP客戶端IP:/127.0.0.1
UDP客戶端端口:53472

精美而實用的網站,提供C語言、C++、STL、Linux、Shell、Java、Go語言等教程,以及socket、GCC、vi、Swing、設計模式、JSP等專題。

Copyright ?2011-2018 biancheng.net, 陜ICP備15000209號

底部Logo
极速pk10开户