程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> Java網絡編程基礎(三) Datagram類使用方法

Java網絡編程基礎(三) Datagram類使用方法

編輯:關於JAVA

 Datagram(數據包)是一種盡力而為的傳送數據的方式,它只是把數據的目的地記錄在數據包中,然後就直接放在網絡上,系統不保證數據是否能安全送到,或者什麼時候可以送到,也就是說它並不保證傳送質量。

  1 UDP套接字

  數據報(Datagram)是網絡層數據單元在介質上傳輸信息的一種邏輯分組格式,它是一種在網絡中傳播的、獨立的、自身包含地址信息的消息,它能否到達目的地、到達的時間、到達時內容是否會變化不能准確地知道。它的通信雙方是不需要建立連接的,對於一些不需要很高質量的應用程序來說,數據報通信是一個非常好的選擇。還有就是對實時性要求很高的情況,比如在實時音頻和視頻應用中,數據包的丟失和位置錯亂是靜態的,是可以被人們所忍受的,但是如果在數據包位置錯亂或丟失時要求數據包重傳,就是用戶所不能忍受的,這時就可以利用UDP協議傳輸數據包。在Java的Java.Net包中有兩個類DatagramSocket和DatagramPacket,為應用程序中采用數據報通信方式進行網絡通信。

  使用數據包方式首先將數據打包,Java.Net包中的DategramPacket類用來創建數據包。數據包有兩種,一種用來傳遞數據包,該數據包有要傳遞到的目的地址;另一種數據包用來接收傳遞過來的數據包中的數據。要創建接收的數據包,通過DatagramPackett類的方法構造:

  public DatagramPacket(byte ibuft[],int ilength)

  public DatagramPacket( byte ibuft[],int offset ,int ilength)

  ibuf[]為接受數據包的存儲數據的緩沖區的長度,ilength為從傳遞過來的數據包中讀取的字節數。當采用第一種構造方法時,接收到的數據從ibuft[0]開始存放,直到整個數據包接收完畢或者將ilength的字節寫入ibuft為止。采用第二種構造方法時,接收到的數據從ibuft[offset]開始存放。如果數據包長度超出了ilength,則觸發IllegalArgument-Exception。不過這是RuntimeException,不需要用戶代碼捕獲。示范代碼如下:

  byte[ ] buffer=new byte[8912];

  DatagramPacket datap=new DatagramPacket(buffer ,buffer.length( ));

  創建發送數據包的構造方法為:

  public DatagramPacket(byt ibuf[],int ilength,InetAddrss iaddr,int port)

  public DatagramPacket(byt ibuf[],int offset , int ilength,InetAddrss iaddr,int port)

  iaddr為數據包要傳遞到的目標地址,port為目標地址的程序接受數據包的端口號(即目標地址的計算機上運行的客戶程序是在哪一個端口接收服務器發送過來的數據包)。ibuf[]為要發送數據的存儲區,以ibuf數組的offset位置開始填充數據包ilength字節,如果沒有offset,則從ibuf數組的0位置開始填充。以下示范代碼是要發送一串字符串:

  String s = new String("Java networking");

  byte[ ] data=s.getbytes();

  int port=1024;

  try{

  InetAddress ineta= InetAddress.getByName(" 169.254.0.14");

  DatagramPacket datap=new DatagramPacket

  (data ,data.length( ),ineta,port);

  }

  catch(IOException e) {

  }

  數據包也是對象,也有操作方法用來獲取數據包的信息,這是很有用的。其方法如下:

  public InetAddress getAddress() 如果是發送數據包,則獲得數據包要發送的目標地址,但是如果是接收數據包則返回發送此數據包的源地址。

  public byte[]getData()

  返回一個字節數組,其中是數據包的數據。如果想把字節數組轉換成別的類型就要進行轉化。如果想轉化成String類型,可以進行以下的處理,設DatagramPacket datap為:

  String s = new String(datap.getbytes());

  public int getLength() 獲得數據包中數據的字節數。

  pubic int getPort( ) 返回數據包中的目標地址的主機端口號。

  發送和接收數據包還需要發送和接收數據包的套接字,即DatagramSocket對象,DatagramSocket套接字在本地機器端口監聽是否有數據到達或者將數據包發送出去。其構造方法如下。

  public DatagramSocket() 用本地機上任何一個可用的端口創建一個套接字,這個端口號是由系統隨機產生的。使用方法如下:

  try{

  DatagramSocket datas=new DatagramSocket( );

  //發送數據包

  }

  catch(SocketException e){

  }

  這種構造方法沒有指定端口號,可以用在客戶端。如果構造不成功則觸發SocketException異常。

  public DatagramSocket(int port)

  用一個指定的端口號port創建一個套接字。

  當不能創建套接字時就拋出SocketException異常,其原因是指定的端口已被占用或者是試圖連接低於1024的端口,但是又沒有具備權限。

  2 實例:利用DatagramSocket查詢端口占用情況

  我們可以利用這個異常探查本地機的端口號有沒有服務。見示例12-9。

  【程序源代碼】

  1 // ==================== Program Description =====================

  2 // 程序名稱:示例12-9: UDPScan.Java

  3 // 程序目的:熟悉DatagramSocket的基本用法,查詢端口的占用情況

  4 //=========================================================

  5 import Java.Net.*;

  6

  7 public class UDPScan

  8 {

  9 public static void main(String args[])

  10 {

  11 for (int port=1024;port<=65535;port++) {

  12 try {

  13 DatagramSocket server=new DatagramSocket(port);

  14 server.close();

  15 }

  16 catch(SocketException e) {

  17 System.out.println("there is a server in port "+port+".");

  18 }

  19 }

  20 }

  21 }

  【程序輸出結果】

  there is a server in port 1026.

  there is a server in port 1028.

  there is a server in port 1046.

  there is a server in port 1900.

  【程序注解】

  在第11~19行我們用for循環以端口號為參數實例化 DatagramSocket,其中端口號從1024到65535。如果在實例過程中出錯,會拋出SocketException異常。我們根據這個異常就可以判斷出哪些端口被占用,哪些還是空閒的。值得一提的是,我們在實例化了DatagramSocket後,調用了close()關閉它。作為一種好的作風,應該遵循。端口號在1024以下的系統可能會用到,比如HTTP默認為80端口,FTP默認為21端口,等等,所以我們從1024端口開始探查。

  套接字對象也有相應的方法,例如發送數據包的方法還有接收數據包的方法,介紹如下。

  pubic void close() 當我們創建一個套接字後,用該方法關閉套接字。

  public int getLocalPort() 返回本地套接字的正在監聽的端口號。

  public void receive(DatagramPacket p) 從網絡上接收數據包並將其存儲在DatagramPacket對象p中。p中的數據緩沖區必須足夠大,receive()把盡可能多的數據存放在p中,如果裝不下,就把其余的部分丟棄。接收數據出錯時會拋出IOException異常。

  public Void Send(DatagramPacket p) 發送數據包,出錯時會發生IOException異常。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved