UDP方式的傳輸
- 2019 年 10 月 18 日
- 筆記
UDP
部分內容需要查文檔學習,我們需要了解下面的兩個類:java.net.DatagramSocket和java.net.DatagramPacket
java.net.DatagramSocket:
- 此類表示用來發送和接收數據報包的套接字。它就像數據傳輸過程中的司機或者接站員一樣,它指引著數據發送的方向和傳輸到達的地方
構造方法:
-
DatagramSocket() 構造數據報套接字並將其綁定到本地主機上任何可用的埠。
-
DatagramSocket(int port, InetAddress laddr) 創建數據報套接字,將其綁定到指定的本地地址。
常用的方法:
-
send(DatagramPacket p) 從此套接字發送數據報包。
-
receive(DatagramPacket p)從此套接字接收數據報包。
-
close() 關閉此數據報套接字。
java.net.DatagramPacket:
- 此類表示數據報包。它就像數據傳輸中的交通工具,就是它承載著數據在主機之間傳輸,這個對象將數據打了個包,裡面不光封裝了數據內容,還有數據的來源,發送數據的主機IP埠等等都一併被封裝到了裡面。
構造方法:
-
DatagramPacket(byte[] buf, int offset, int length, InetAddress address, int port)
構造數據報包,用來將長度為 length 偏移量為 offset 的包發送到指定主機上的指定埠號。 -
DatagramPacket(byte[] buf, int length, InetAddress address, int port)
構造數據報包,用來將長度為 length 的包發送到指定主機上的指定埠號。 -
DatagramPacket(byte[] buf, int length)
構造 DatagramPacket,用來接收長度為 length 的數據包。
UDP接收端
先寫一個UDP的接收端,大概思路就是,先通過
DatagramSocket ds = new DatagramSocket(10003);
new一個對象,這個對象用來發送和接收數據包的套接字。然後通過
DatagramPacket dp = new DatagramPacket(buf, buf.length);
定義數據包,最後調用recieve函數來接收數據,並將數據封裝在數據包中。
值得注意的是發送端的發送至的IP地址及其埠必須和接收端的主機IP以及埠相對應
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UdpRecieve { public static void main(String[] args) throws IOException, IOException { System.out.println("udp 接收端......run"); /** * 定義一個udp的接收端,接收發送過來的數據。並顯示在螢幕上 * * 思路: * 1、先有udp socket服務,就是先有插座。 而且記住:接收端一定要明確埠,否則,收不到數據 * 2、接受數據。之前應該先將數據存儲到數據包中。因為數據還有解析 * 3、先定義數據包 * 4、通過數據包對象獲取數據包的內容,發送端的ip、發送端的埠、發送過來的數據 * 5、關閉資源 * */ //1、先有udp socket服務,就是先有插座。而且記住:接收端一定要明確埠,否則,收不到數據 DatagramSocket ds = new DatagramSocket(10000); //2、接受數據。之前應該先將數據存儲到數據包中。因為數據還有解析 //3、先定義數據包 byte[] buf = new byte[1024]; //緩衝區,保存數據 DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); //阻塞,在接受到數據之前一直處於阻塞狀態,類似於輸入操作 //4、通過數據包對象獲取數據包的內容,發送端的ip、發送端的埠、發送過來的數據 String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String text = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+"---:---"+port+"---:---"+text); //5、關閉資源 ds.close(); } }
將其裝在一個while(true)循環里,可以持續接收數據
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; public class UdpRecieve2 { public static void main(String[] args) throws IOException, IOException { System.out.println("udp 接收端 run"); /** * 定義一個udp的接收端,接收發送過來的數據。並顯示在螢幕上 * * 思路: * 1、先有udp socket服務,就是先有插座。 而且記住:接收端一定要明確埠,否則,收不到數據 * 2、接受數據。之前應該先將數據存儲到數據包中。因為數據還有解析 * 3、先定義數據包 * 4、通過數據包對象獲取數據包的內容,發送端的ip、發送端的埠、發送過來的數據 * 5、關閉資源 * */ //1、先有udp socket服務,就是先有插座嘛。而且記住:接收端一定要明確埠,否則,收不到數據 DatagramSocket ds = new DatagramSocket(10000); while(true) { //2、接受數據。之前應該先將數據存儲到數據包中。因為數據還有解析 //3、先定義數據包 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf, buf.length); ds.receive(dp); //阻塞 //4、通過數據包對象獲取數據包的內容,發送端的ip、發送端的埠、發送過來的數據 String ip = dp.getAddress().getHostAddress(); int port = dp.getPort(); String text = new String(dp.getData(),0,dp.getLength()); System.out.println(ip+":"+port+": "+text); } } }
UDP發送端
用下面這句先創建一個socket來指引數據的去向,這個裡面的參數「8888」表示的不是發送目的地主機的埠,而是發送起點的埠,表示從這個主機的8888埠發出去的。
DatagramSocket ds = new DatagramSocket(8888);
然後再用下面這句將數據內容,發送的目的地都封裝到這麼一個數據包裡面,裡面的參數buf表示位元組數組,必須是位元組數組,不能是字元串數組,buf.length無疑是傳輸的長度, InetAddress.getByName("127.255.25.1")是目的地的主機地址,這句的含義是通過ip地址獲取主機地址,10000表示目的地接收這個數據的埠,這個埠要保證沒有被其他應用佔用。
DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.255.25.1"), 10000);
最後調用send函數即可完成發送
import java.io.IOException; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UdpSend { public static void main(String[] args) throws IOException, IOException { System.out.println("udp 發送端 run"); /** * 通過查閱文檔,了解到用於UDP傳輸協議的對象是DatagramSocket * * 通過UDP協議發送一段文本數據 * 思路: * 1、需要先建立UDP的socket。它具備發送和接收功能 * 2、將數據封裝到數據包中。數據包對象是DatagramPacket * 3、使用socket對象的send方法將數據包發送出去 * 4、關閉資源 * */ //1、需要先建立UDP的socket。它具備發送和接收功能 DatagramSocket ds = new DatagramSocket(8888); //2、將數據封裝到數據包中。數據包對象是DatagramPacket String text = "hello udp來了!"; byte[] buf = text.getBytes(); //將數據轉成位元組數組 //將位元組數組封裝到數據包中 DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.255.25.1"), 10000); //3、使用socket對象的send方法將數據包發送出去 ds.send(dp); //4、關閉資源 ds.close(); } }
發送鍵盤輸入的數據,這裡其實就是加了鍵盤錄入,IO流的操作
import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; import java.net.DatagramPacket; import java.net.DatagramSocket; import java.net.InetAddress; public class UdpSend2 { public static void main(String[] args) throws IOException, IOException { System.out.println("udp 發送端 run"); /** * 通過查閱文檔,了解到用於UDP傳輸協議的對象是DatagramSocket * * 通過UDP協議發送一段文本數據 思路: * 1、需要先建立UDP的socket。它具備發送和接收功能 * 2、將數據封裝到數據包中。數據包對象是DatagramPacket * 3、使用socket對象的send方法將數據包發送出去 * 4、關閉資源 */ // 1、需要先建立UDP的socket。它具備發送和接收功能 DatagramSocket ds = new DatagramSocket(9999); // 2、將數據封裝到數據包中。數據包對象是DatagramPacket。數據來自於鍵盤錄入 BufferedReader bufr = new BufferedReader(new InputStreamReader(System.in)); String line = null; while ((line = bufr.readLine()) != null) { if("over".equals(line)) break; byte[] buf = line.getBytes(); // 將數據轉成位元組數組 // 將位元組數組封裝到數據包中 DatagramPacket dp = new DatagramPacket(buf, buf.length, InetAddress.getByName("127.255.25.1"), 10000); ds.send(dp); } // 4、關閉資源 ds.close(); } }
成功示例:
發送前
從鍵盤錄入發送內容
接收端