UDP
我的另一篇文章TCP方式的傳輸
部分內容需要查文檔學習,我們需要了解下面的兩個類: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();
}
}
成功示例:
發送前

從鍵盤錄入發送內容

接收端

