UDP的網路編程
一 :UDP的基本概念
? UDP協議的全稱是用戶資料報,在網路中它與TCP協議一樣用于處理資料包,在OSI模型中,在第四層——傳輸層,處于IP協議的上一層,UDP有不提供資料報分組、組裝和不能對資料包的排序的缺點,也就是說,當報文發送之后,是無法得知其是否安全完整到達的,
二:使用UDP的原因
? 它不屬于連接型協議,因而具有資源消耗小,處理速度快的優點,所以通常音頻、視頻和普通資料在傳送時使用UDP較多,因為它們即使偶爾丟失一兩個資料包, 也不會對接收結果產生太大影響,比如我們聊天用的ICQ和OICQ就是使用的UDP協議,在選擇使用協議的時候,選擇UDP必須要謹慎,在網路質量令人不 十分滿意的環境下,UDP協議資料包丟失會比較嚴重,
三:JAVA中UDP的API類
- InetAddress: 用于描述和包裝一個Internet IP地址,
| 方法名 | 回傳值 | |
|---|---|---|
| getLocalhost() | 回傳封裝本地地址的實體 | |
| getAllByName(String host) | 回傳封裝Host地址的InetAddress實體陣列 | |
| getByName(String host) | 回傳一個封裝Host地址的實體,其中,Host可以是域名或者是一個合法的IP地址, | |
| InetAddress.getByAddress(addr) | 根據地址串回傳InetAddress實體 |
- DatagramSocket: 用于接收和發送UDP的Socket實體,
| 方法名 | 回傳值 | |
|---|---|---|
| DatagramSocket() | 通常用于客戶端編程,它并沒有特定監聽的埠,僅僅使用一個臨時的,程式會讓作業系統分配一個可用的埠 | |
| DatagramSocket(int port) | 創建實體,并固定監聽Port埠的報文,通常用于服務端 | |
| DatagramSocket(int port, InetAddress localAddr) | 這是個非常有用的構建器,當一臺機器擁有多于一個IP地址的時候,由它創建的實體僅僅接收來自LocalAddr的報文, | |
| receive(DatagramPacket d) | 接收資料報文到d中,receive方法產生一個“阻塞”,“阻塞”是一個專業名詞,它會產生一個內部回圈,使程式暫停在這個地方,直到一個條件觸發, | |
| send(DatagramPacket dp) | 發送報文dp到目的地 | |
| setSoTimeout(int timeout) | 設定超時時間,單位為毫秒, | |
| close() | 應用程式退出的時候,通常會主動釋放資源,關閉Socket,但是由于例外地退出可能造成資源無法回收,所以,應該在程式完成時,主動使用此方法關閉Socket,或在捕獲到例外拋出后關閉Socket, |
- DatagramPacket:用于處理報文,它將Byte陣列、目標地址、目標埠等資料包裝成報文或者將報文拆卸成Byte陣列,
| 方法名 | 回傳值 | |
|---|---|---|
| DatagramPacket(byte[] buf, int length) | 將資料包中Length長的資料裝進Buf陣列,一般用來接收客戶端發送的資料 | |
| DatagramPacket(byte[] buf, int offset, int length) | 將資料包中從Offset開始、Length長的資料裝進Buf陣列 | |
| DatagramPacket(byte[] buf, int length, InetAddress clientAddress, int clientPort) | 從Buf陣列中,取出Length長的資料創建資料包物件,目標是clientAddress地址,clientPort埠, 通常用來發送資料給客戶端, | |
| DatagramPacket(byte[] buf, int offset, int length, InetAddress clientAddress, int clientPort) | 從Buf陣列中,取出Offset開始的、Length長的資料創建資料包物件,目標是clientAddress地 址,clientPort埠,通常用來發送資料給客戶端, | |
| getData() | 從實體中取得報文的Byte陣列編碼, | |
| setDate(byte[] buf) | 將byte陣列放入要發送的報文中, |
四:java中UDP的網路編程示例
- 基礎版本
//UDP服務端
public class BaseUdpServer {
public static void main(String[] args) throws IOException {
System.out.println("基礎版UDP服務器啟動....");
//定義UDP服務端socket
DatagramSocket datagramSocket = new DatagramSocket(8888);
//接受客戶端傳遞過來的容器
byte[] contain = new byte[1024];
//解包程序
DatagramPacket datagramPacket = new DatagramPacket(contain,contain.length);
//等待接受訊息阻塞
datagramSocket.receive(datagramPacket);
//列印訊息
System.out.println(new String(contain,0,datagramPacket.getLength()));
}
}
//UDP的客戶端
public class BaseUdpClient {
public static void main(String[] args) throws IOException {
System.out.println("基礎版UDP客戶端啟動....");
//定義UDP客戶端socket
DatagramSocket datagramSocket = new DatagramSocket(6666);
//定義發送的訊息
String msg = "hello UDP";
//裝包程序(注意:需要指定服務器端的IP和埠號)
DatagramPacket datagramPacket = new DatagramPacket(msg.getBytes(),
msg.getBytes().length,
InetAddress.getByName("localhost"),
8888);
//發送訊息
System.out.println("訊息發送中,發送的訊息為: msg = " + msg);
datagramSocket.send(datagramPacket);
//關閉連接
datagramSocket.close();
}
}
執行結果為:


2) 發送基本型別資料
//客戶端
public class BaseUdpTypeClient {
public static void main(String[] args) throws IOException {
System.out.println("基本型別UDP客戶端啟動....");
//定義UDP服務端socket
DatagramSocket datagramSocket = new DatagramSocket(6666);
//首先思路,要將基本型別轉化成位元組資料,需要用到兩個IO流
//位元組陣列輸出流
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
//資料輸出流
DataOutputStream dataOutputStream = new DataOutputStream(
new BufferedOutputStream(byteArrayOutputStream));
//輸出字符型別
dataOutputStream.writeUTF("UTF-8");
//輸出數字型別
dataOutputStream.writeInt(12);
//輸出double型別
dataOutputStream.writeDouble(12.00);
//輸出boolean型別
dataOutputStream.writeBoolean(true);
//資料的重繪
dataOutputStream.flush();
//解包程序
DatagramPacket datagramPacket = new DatagramPacket(byteArrayOutputStream.toByteArray(),0,
byteArrayOutputStream.toByteArray().length,
InetAddress.getByName("localhost"),
8888);
//發送訊息
System.out.println("訊息發送中,發送的訊息為: msg = \"UTF-8\"");
System.out.println("訊息發送中,發送的訊息為: msg = 12");
System.out.println("訊息發送中,發送的訊息為: msg = 12.00");
System.out.println("訊息發送中,發送的訊息為: msg = true");
datagramSocket.send(datagramPacket);
//關閉連接
dataOutputStream.close();
byteArrayOutputStream.close();
datagramSocket.close();
}
}
//服務端
public class BaseUdpTypeServer {
public static void main(String[] args) throws IOException {
System.out.println("基礎型別UDP服務器啟動....");
//定義UDP服務端socket
DatagramSocket datagramSocket = new DatagramSocket(8888);
//接受客戶端傳遞過來的容器
byte[] contain = new byte[1024];
//解包程序
DatagramPacket datagramPacket = new DatagramPacket(contain,contain.length);
//阻塞訊息
datagramSocket.receive(datagramPacket);
//獲取位元組資料
byte[] data = datagramPacket.getData();
//獲取位元組資料長度
int length = datagramPacket.getLength();
//獲取資料流
ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(data,0,length);
DataInputStream dataInputStream = new DataInputStream(new BufferedInputStream(byteArrayInputStream));
System.out.println(dataInputStream.readUTF());
System.out.println(dataInputStream.readInt());
System.out.println(dataInputStream.readDouble());
System.out.println(dataInputStream.readBoolean());
//關閉
datagramSocket.close();
}
}
執行結果:


轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/258411.html
標籤:java
