JAVA中UDP使用


UDP協議

在有些應用程序中,保持最快的速度比保證每一位數據都正確到達更重要。例如,在實時音頻或視頻中,丟失數據包只會作為干擾出現。干擾是可以容忍的,但當TCP請求重傳或等待數據包到達而它卻遲遲不到時,音頻流中就會出現尷尬的停頓,這讓人無法接受的。在其他應用中,可以在應用層實現可靠性傳輸。例如:如果客戶端向服務器發送一個短的UDP請求,倘若制定時間內沒有響應返回,它會認為這個包已丟失。域名系統就是采用這樣的工作方式。事實上,可以用UDP實現一個可靠的文件傳輸協議,而且很多人確實是這樣做的:網絡文件系統,簡單FTP都使用了UDP協議。在這些協議中由應用程序來負責可靠性。java中的UDP實現分為兩個類:DatagramPacketDatagramSocket。DatagramPacket類將數據字節填充到UDP包中,這稱為數據報。 DatagramSocket來發送這個包。要接受數據,可以從DatagramSocket中接受一個 DatagramPack對象,然后從該包中讀取數據的內容。

這種職責的划分與TCP使用的Socket和ServerSocket有所不同。首先,UDP沒有兩台主機間唯一連接的概念,它不需要知道對方是哪個遠程主機。它可以從一個端口往多個主機發送信息,但是TCP是無法做到的。其次,TCP socket把網絡鏈接看作是流:通過從Socket得到的輸入和輸出流來收發數據。UDP不支持這一點,你處理總是單個數據包。填充在一個數據報中的所有數據會以包的形式進行發送,這些數據要么作為一個組要么全部接收,要么全部丟棄。一個包不一定與下一個包相關。給定兩個包,沒有辦法知道哪個先發哪個后發。對於流來說,必須提供數據的有序隊列,與之不同,數據報會盡可能快的蜂擁到接收方。

一個UDP客戶端

package com.dy.xidian;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

public class DaytimeUDPClient {
	
	private final static int PORT = 13;
	private static final String HOSTNAME = "www.xdysite.cn";
	
	
	public static void main(String[] args) {
		//傳入0表示讓操作系統分配一個端口號
		try (DatagramSocket socket = new DatagramSocket(0)) {
			socket.setSoTimeout(10000);
			InetAddress host = InetAddress.getByName(HOSTNAME);
			//指定包要發送的目的地
			DatagramPacket request = new DatagramPacket(new byte[1], 1, host, PORT);
			//為接受的數據包創建空間
			DatagramPacket response = new DatagramPacket(new byte[1024], 1024);
			socket.send(request);
			socket.receive(response);
			String result = new String(response.getData(), 0, response.getLength(), "ASCII");
			System.out.println(result);
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

一個UDP服務器

package com.dy.xidian;

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.util.Date;

public class DaytimeUDPServer {

	private final static int PORT = 13;
	
	public static void main(String[] args) {
		try (DatagramSocket socket = new DatagramSocket(PORT)) {
			while (true) {
				try {
					DatagramPacket request = new DatagramPacket(new byte[1024], 1024);
					socket.receive(request);
					
					String daytime = new Date().toString();
					byte[] data = daytime.getBytes("ASCII");
					DatagramPacket response = new DatagramPacket(data, data.length, request.getAddress(), request.getPort());
					socket.send(response);
					System.out.println(daytime + " " + request.getAddress());
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM