什麼是UDP協議
UDP協議的全稱是用戶數據報在網絡中它與TCP協議一樣用於處理數據包在OSI模型中在第四層——傳輸層處於IP協議的上一層UDP有不提供數據報分組組裝和不能對數據包的排序的缺點也就是說當報文發送之後是無法得知其是否安全完整到達的
為什麼要使用UDP
在選擇使用協議的時候選擇UDP必須要謹慎在網絡質量令人不十分滿意的環境下UDP協議數據包丟失會比較嚴重但是由於UDP的特性它不屬於連接型協議因而具有資源消耗小處理速度快的優點所以通常音頻視頻和普通數據在傳送時使用UDP較多因為它們即使偶爾丟失一兩個數據包也不會對接收結果產生太大影響比如我們聊天用的ICQ和OICQ就是使用的UDP協議
在Java中操縱UDP
使用位於JDK中包下的DatagramSocket和DatagramPacket類可以非常方便地控制用戶數據報文
在描述它們之前必須了解位於同一個位置的InetAddress類InetAddress實現了Javaio Serializable接口不允許繼承它用於描述和包裝一個Internet IP地址通過三個方法返回InetAddress實例
getLocalhost()返回封裝本地地址的實例
getAllByName(String host)返回封裝Host地址的InetAddress實例數組
getByName(String host)返回一個封裝Host地址的實例其中Host可以是域名或者是一個合法的IP地址
DatagramSocket類用於創建接收和發送UDP的Socket實例和Socket類依賴SocketImpl類一樣DatagramSocket類的實現也依靠專門為它設計的DatagramScoketImplFactory類DatagramSocket類有個構建器
DatagramSocket()創建實例這是個比較特殊的用法通常用於客戶端編程它並沒有特定監聽的端口僅僅使用一個臨時的
DatagramSocket(int port)創建實例並固定監聽Port端口的報文
DatagramSocket(int port InetAddress localAddr)這是個非常有用的構建器當一台機器擁有多於一個IP地址的時候由它創建的實例僅僅接收來自LocalAddr的報文
值得注意的是在創建DatagramSocket類實例時如果端口已經被使用會產生一個SocketException的異常拋出並導致程序非法終止這個異常應該注意捕獲DatagramSocket類最主要的方法有個
Receive(DatagramPacket d)接收數據報文到d中receive方法產生一個阻塞
Send(DatagramPacket d)發送報文d到目的地
SetSoTimeout(int timeout)設置超時時間單位為毫秒
Close()關閉DatagramSocket在應用程序退出的時候通常會主動釋放資源關閉Socket但是由於異常地退出可能造成資源無法回收所以應該在程序完成時主動使用此方法關閉Socket或在捕獲到異常拋出後關閉Socket
阻塞是一個專業名詞它會產生一個內部循環使程序暫停在這個地方直到一個條件觸發
DatagramPacket類用於處理報文它將Byte數組目標地址目標端口等數據包裝成報文或者將報文拆卸成Byte數組應用程序在產生數據包是應該注意TCP/IP規定數據報文大小最多包含個通常主機接收個字節但大多數平台能夠支持字節大小的報文DatagramPacket類的構建器共有個
DatagramPacket(byte[] buf int length InetAddress addr int port)從Buf數組中取出Length長的數據創建數據包對象目標是Addr地址Port端口
DatagramPacket(byte[] buf int offset int length InetAddress address int port)從Buf數組中取出Offset開始的Length長的數據創建數據包對象目標是Addr地址Port端口
DatagramPacket(byte[] buf int offset int length)將數據包中從Offset開始Length長的數據裝進Buf數組
DatagramPacket(byte[] buf int length)將數據包中Length長的數據裝進Buf數組
DatagramPacket類最重要的方法就是getData()了它從實例中取得報文的Byte數組編碼
簡單的實例說明
{接收數據的服務器}
byte[] buf = new byte[];
DatagramSocket ds = new DatagramSocket();
//開始監視端口
DatagramPacket ip = new DatagramPacket(buf buflength);
//創建接收數據報的實例
while (true)
{
dsreceive(ip);
//阻塞直到收到數據報後將數據裝入IP中
Systemoutprintln(new String(buf));
}
{發送數據的客戶端}
InetAddress target = InetAddressgetByName();
//得到目標機器的地址實例
DatagramSocket ds = new DatagramSocket();
//從端口發送數據報
String hello = Hello I am come in!;
//要發送的數據
byte[] buf = hellogetBytes();
//將數據轉換成Byte類型
op = new DatagramPacket(buf buflength target );
//將BUF緩沖區中的數據打包
dssend(op);
//發送數據
dsclose();
//關閉連接
From:http://tw.wingwit.com/Article/program/Java/hx/201311/25850.html