歡迎來到Linux教程網
Linux教程網
Linux教程網
Linux教程網
Linux教程網 >> Linux編程 >> Linux編程 >> Java編程高級之UDP協議編程在Java中的體現

Java編程高級之UDP協議編程在Java中的體現

日期:2017/3/1 10:10:10   编辑:Linux編程
要實現UDP協議編程就要知道什麼是UDP協議、我們為什麼要使用UDP協議編程以及在Java中是如何實現UDP編程的,這些都是值得我們思考的。

所謂的UDP( User Datagram Protocol )協議指的是用戶數據報,在網絡中它與TCP協議一樣用於處理數據包。在OSI模型中,在第四層——傳輸層,處於IP協議的上一層。

UDP是一種無連接的協議,每個數據報都是一個獨立的信息,包括完整的源或目的地址,它在網絡上以任何可能的路徑傳往目的地,因此能否到達目的地,到達目的地的時間以及內容的正確性都是不能被保證的。

既然如此,那麼我們為什麼還要使用UDP協議進行編程呢?

那是因為,在網絡質量令人不十分滿意的環境下,UDP協議數據包丟失會比較嚴重。但是由於UDP的特性:它不屬於連接型協議,因而具有資源消耗小,處理速度快的優點,所以通常音頻、視頻和普通數據在傳送時使用UDP較多,因為它們即使偶爾丟失一兩個數據包,也不會對接收結果產生太大影響。比如聊天用的ICQ和OICQ

在Java中操縱UDP

使用位於JDK中Java.net包下的DatagramSocket和DatagramPacket類,就可以非常方便地控制用戶數據報文了。

其中,DatagramSocket類:創建接收和發送UDP的Socket實例

  • DatagramSocket():創建實例。通常用於客戶端編程,它並沒有特定監聽的端口,僅僅使用一個臨時的。
  • DatagramSocket(int port):創建實例,並固定監聽Port端口的報文。
  • DatagramSocket(int port,InetAddress localAddr):這是個非常有用的構建器,當一台機器擁有多於一個IP地址的時候,由它創建的實例僅僅接收來自LocalAddr的報文。

值得注意的是,在創建DatagramSocket類實例時,如果端口已經被使用,會產生一個SocketException的異常拋出,並導致程序非法終止,這個異常應該注意捕獲。

還有一些重要的實現方法,如:

receive(DatagramPacket d):接收數據報文到d中。receive方法產生一個“阻塞”。

send(DatagramPacketd):發送報文d到目的地。

setSoTimeout(inttimeout):設置超時時間,單位為毫秒。

close():關閉DatagramSocket。在應用程序退出的時候,通常會主動釋放資源,關閉

Socket,但是由於異常地退出可能造成資源無法回收。所以,應該在程序完成時,主動使用此方法關閉Socket,或在捕獲到異常拋出後關閉Socket。

注意:“阻塞”是一個專業名詞,它會產生一個內部循環,使程序暫停在這個地方,直到一個條件觸發。

實現UDP編程會使用到的另一個十分重要的類,DatagramPacket類。

DatagramPacket:用於處理報文,將byte數組、目標地址、目標端口等數據包裝成報文或者將報文拆卸成byte數組。

DatagramPacket(byte[] buf, int length, InetAddress addr, int port):從buf數組中,取出length長的數據創建數據包對象,目標是addr地址,port端口。

DatagramPacket(byte[] buf, int offset, int length, InetAddressaddress, int port):從buf數組中,取出offset開始的、length長的數據創建數據包對象,目標是addr地址,port端口。

DatagramPacket(byte[] buf, int offset, int length):將數據包中從offset開始、length長的數據裝進buf數組。

DatagramPacket(byte[] buf, int length):將數據包中length長的數據裝進buf數組。

getData():它從實例中取得報文的byte數組編碼。

使用UDP協議編程,最主要的是編寫發送端和接收端的程序。對於這兩部分代碼的編寫,也是非常容易的,因為,它們都有一定的編寫步驟和規范。

如對於發送端的編寫:

發送端

建立udpsocket服務端點。該端點建立,系統會隨機分配一個端口。如果不想隨機配置,可以手動指定。
DatagramSocket ds = new DatagramSocket(9002);

將數據進行packet包的封裝,必須要指定目的地地址和端口。
byte[] buf = "wo shi shu ju".getBytes();
            DatagramPacket dp=newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),9001);

通過socket服務的send方法將該包發出。
ds.send(dp);

將socket服務關閉。主要是關閉資源。
ds.close();

這樣,就完成了對於發送端的編寫工作了。另外,

接收端

建立udpsocket服務端點。該端點建立,系統會隨機分配一個端口。如果不想隨機配置,可以手動指定。
DatagramSocket ds = new DatagramSocket(9002);

將數據進行packet包的封裝,必須要指定目的地地址和端口。
byte[] buf = "wo shi shu ju".getBytes();
                      DatagramPacket   dp=newDatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.254"),9001);

通過socket服務的send方法將該包發出。
ds.send(dp);

將socket服務關閉。主要是關閉資源。
ds.close();

關於發送端和接收端應用的兩個程序:

發送端:

package net.csdn.udt;

import java.net.DatagramPacket;

import java.net.DatagramSocket;

import java.net.InetAddress;

import java.net.InetSocketAddress;

public class Send {

/**

* @param args

*/

public static voidmain(String[] args)throws Exception {

//建立udpsocket服務端點。該端點建立,系統會隨機分配一個端口。

DatagramSocket ds = new DatagramSocket();

//將數據進行packet包的封裝,必須要指定目的地地址和端口。

byte [] buf ="wo shi shu ju".getBytes();

//創建數據報對象

String host = "192.168.49.110";

InetAddress ia = InetAddress.getByName(host);

DatagramPacket dp = new DatagramPacket(buf,buf.length, ia,3366);

//通過socket服務的send方法將該包發出。

ds.send(dp);

//將socket服務關閉。主要是關閉資源。

ds.close();

}

}

接收端:

packagenet.csdn.udt;

importjava.net.DatagramPacket;

importjava.net.DatagramSocket;

importjava.net.InetAddress;

public classReceive {

/**

*@param args

*/

public static void main(String[] args)throws Exception{

//創建一個udt的接收對象

DatagramSocket ds =newDatagramSocket(9009);

//將接收的數據封裝成數據包中

byte[] buf = new byte [1024];

//創建數據報對象

DatagramPacket dp = newDatagramPacket(buf,buf.length);

//接收數據報

ds.receive(dp);

//輸出

//InetAddress host = dp.getAddress();

String data =new String(dp.getData());

String host =dp.getAddress().getHostAddress();

int port =dp.getPort();

System.out.println("data:\t"+data+"host:\t"+host+"port:\t"+port);

ds.close();

}

}

對於Socket編程的一些方法步驟,我們一定要熟記並且要經常練習、運用以免忘記,因為,它還是挺重要的。

Copyright © Linux教程網 All Rights Reserved