數據庫中java的DatagramPacket
自尋址套接字(Datagram Sockets)
,因為使用流套接字的每個(gè)連接均要花費一定的時(shí)間,要減少這種開(kāi)銷(xiāo),網(wǎng)絡(luò )API提供了第二種套接字:自尋址套接字 (datagram socket),自尋址使用UDP發(fā)送尋址信息(從客戶(hù)程序到服務(wù)程序或從服務(wù)程序到客戶(hù)程序),不同的是可以通過(guò)自尋址套接字發(fā)送 多IP信息包,自尋址信息包含在自尋址包中,此外自尋址包又包含在IP包內,這就將尋址信息長(cháng)度限制在60000字節內。圖2顯示了位于IP包內的自尋址 包的自尋址信息。
與TCP保證信息到達信息目的地的方式不同,UDP提供了另外一種方法,如果自尋址信息包沒(méi)有到達目的地,,那么UDP也不會(huì )請求發(fā)送者重新發(fā) 送自尋址包,這是因為UDP在每一個(gè)自尋址包中包含了錯誤檢測信息,在每個(gè)自尋址包到達目的地之后UDP只進(jìn)行簡(jiǎn)單的錯誤檢查,如果檢測失敗,UDP將拋 棄這個(gè)自尋址包,也不會(huì )從發(fā)送者那里重新請求替代者,這與通過(guò)郵局發(fā)送信件相似,發(fā)信人在發(fā)信之前不需要與收信人建立連接,同樣也不能保證信件能到達收信 人那里
自尋址套接字工作包括下面三個(gè)類(lèi):DatagramPacket, DatagramSocket,和 MulticastSocket。 DatagramPacket對象描繪了自尋址包的地址信息,DatagramSocket表示客戶(hù)程序和服務(wù)程序自尋址套接 字,MulticastSocket描繪了能進(jìn)行多點(diǎn)傳送的自尋址套接字,這三個(gè)類(lèi)均位于java.net包內。
DatagramPacket類(lèi)
在使用自尋址包之前,你需要首先熟悉DatagramPacket類(lèi),地址信息和自尋址包以字節數組的方式同時(shí)壓縮入這個(gè)類(lèi)創(chuàng )建的對象中
DatagramPacket有數個(gè)構造函數,即使這些構造函數的形式不同,但通常情況下他們都有兩個(gè)共同的參 數:byte [] buffer 和 int length,buffer參數包含了一個(gè)對保存自尋址數據包信息的字節數組的引用,length表示字 節數組的長(cháng)度。
最簡(jiǎn)單的構造函數是DatagramPacket(byte [] buffer, int length),這個(gè)構造函數確定了自尋址數據包 數組和數組的長(cháng)度,但沒(méi)有任何自尋址數據包的地址和端口信息,這些信息可以后面通過(guò)調用方法setAddress(InetAddress addr)和 setPort(int port)添加上,下面的代碼示范了這些函數和方法。
byte [] buffer = new byte [100];
DatagramPacket dgp = new DatagramPacket (buffer, buffer.length);
InetAddress ia = InetAddress.getByName ("dgp.setAddress (ia);
dgp.setPort (6000); // Send datagram packet to port 6000.
如果你更喜歡在調用構造函數的時(shí)候同時(shí)包括地址和端口號,可以使用DatagramPacket(byte [] buffer, int length, InetAddress addr, int port)函數,下面的代碼示范了另外一種選擇。
byte [] buffer = new byte [100];
InetAddress ia = InetAddress.getByName ("DatagramPacket dgp = new DatagramPacket (buffer, buffer.length, ia,
6000);
有時(shí)候在創(chuàng )建了DatagramPacket對象后想改變字節數組和他的長(cháng)度,這時(shí)可以通過(guò)調用 setData(byte [] buffer) 和 setLength(int length)方法來(lái)實(shí)現。在任何時(shí)候都可以通過(guò)調用 getData() 來(lái)得到字節數組的引用,通過(guò)調用getLength()來(lái)獲得字節數組的長(cháng)度。下面的代碼示范了這些方法:
byte [] buffer2 = new byte [256];
dgp.setData (buffer2);
dgp.setLength (buffer2.length);
類(lèi)
DatagramSocket類(lèi)在客戶(hù)端創(chuàng )建自尋址套接字與服務(wù)器端進(jìn)行通信連接,并發(fā)送和接受自尋址套接字。雖然有多個(gè)構造函數可供選擇,但 我發(fā)現創(chuàng )建客戶(hù)端自尋址套接字最便利的選擇是DatagramSocket()函數,而服務(wù)器端則是DatagramSocket(int port)函 數,如果未能創(chuàng )建自尋址套接字或綁定自尋址套接字到本地端口,那么這兩個(gè)函數都將拋出一個(gè)SocketException對象,一旦程序創(chuàng )建了 DatagramSocket對象,那么程序分別調用send(DatagramPacket dgp) 和 receive(DatagramPacket dgp)來(lái)發(fā)送和接收自尋址數據包,
List4顯示的DGSClient源代碼示范了如何創(chuàng )建自尋址套接字以及如何通過(guò)套接字處理發(fā)送和接收信息
Listing 4: DGSClient.java
// DGSClient.java
import java.io.*;
import java.net.*;
class DGSClient
{
public static void main (String [] args)
{
String host = "localhost";
// If user specifies a command-line argument, that argument
// represents the host name.
if (args.length == 1)
host = args [0];
DatagramSocket s = null;
try
{
// Create a datagram socket bound to an arbitrary port.
s = new DatagramSocket ();
// Create a byte array that will hold the data portion of a
// datagram packet's message. That message originates as a
// String object, which gets converted to a sequence of
// bytes when String's getBytes() method is called. The
// conversion uses the platform's default character set.
byte [] buffer;
buffer = new String ("Send me a datagram").getBytes ();
// Convert the name of the host to an InetAddress object.
// That object contains the IP address of the host and is
// used by DatagramPacket.
InetAddress ia = InetAddress.getByName (host);
// Create a DatagramPacket object that encapsulates a
// reference to the byte array and destination address
// information. The destination address consists of the
// host's IP address (as stored in the InetAddress object)
// and port number 10000 -- the port on which the server
// program listens.
DatagramPacket dgp = new DatagramPacket (buffer,
buffer.length,
ia,
10000);
// Send the datagram packet over the socket.
s.send (dgp);
// Create a byte array to hold the response from the server.
// program.
byte [] buffer2 = new byte [100];
// Create a DatagramPacket object that specifies a buffer
// to hold the server program's response, the IP address of
// the server program's computer, and port number 10000.
dgp = new DatagramPacket (buffer2,
buffer.length,
ia,
10000);
// Receive a datagram packet over the socket.
s.receive (dgp);
// Print the data returned from the server program and stored
// in the datagram packet.
System.out.println (new String (dgp.getData ()));
}
catch (IOException e)
{
System.out.println (e.toString ());
}
finally
{
if (s != null)
s.close ();
}
}
}
DGSClient由創(chuàng )建一個(gè)綁定任意本地(客戶(hù)端)端口好的DatagramSocket對象開(kāi)始,然后裝入帶有文本信息的數組buffer和描述 服務(wù)器主機IP地址的InetAddress子類(lèi)對象的引用,接下來(lái),DGSClient創(chuàng )建了一個(gè)DatagramPacket對象,該對象加入了帶文 本信息的緩沖器的引用,InetAddress子類(lèi)對象的引用,以及服務(wù)端口號10000, DatagramPacket的自尋址數據包通過(guò)方法 sent()發(fā)送給服務(wù)器程序,于是一個(gè)包含服務(wù)程序響應的新的DatagramPacket對象被創(chuàng )建,receive()得到響應的自尋址數據包,然 后自尋址數據包的getData()方法返回該自尋址數據包的一個(gè)引用,最后關(guān)閉DatagramSocket。
DGSServer服務(wù)程序補充了DGSClient的不足,List5是DGSServer的源代碼:
Listing 5: DGSServer.java
// DGSServer.java
import java.io.*;
import java.net.*;
class DGSServer
{
public static void main (String [] args) throws IOException
{
System.out.println ("Server starting ...\n");
// Create a datagram socket bound to port 10000. Datagram
// packets sent from client programs arrive at this port.
DatagramSocket s = new DatagramSocket (10000);
// Create a byte array to hold data contents of datagram
// packet.
byte [] data = new byte [100];
// Create a DatagramPacket object that encapsulates a reference
// to the byte array and destination address information. The
// DatagramPacket object is not initialized to an address
// because it obtains that address from the client program.
DatagramPacket dgp = new DatagramPacket (data, data.length);
// Enter an infinite loop. Press Ctrl+C to terminate program.
while (true)
{
// Receive a datagram packet from the client program.
s.receive (dgp);
// Display contents of datagram packet.
System.out.println (new String (data));
// Echo datagram packet back to client program.
s.send (dgp);
}
}
}
多點(diǎn)傳送和MulticastSocket類(lèi)
前面的例子顯示了服務(wù)器程序線(xiàn)程發(fā)送單一的消息(通過(guò)流套接字或自尋址套接字)給唯一的客戶(hù)端程序,這種行為被稱(chēng)為單點(diǎn)傳送 (unicasting),多數情況都不適合于單點(diǎn)傳送,比如,搖滾歌手舉辦一場(chǎng)音樂(lè )會(huì )將通過(guò)互聯(lián)網(wǎng)進(jìn)行播放,畫(huà)面和聲音的質(zhì)量依賴(lài)于傳輸速度,服務(wù)器程 序要傳送大約10億字節的數據給客戶(hù)端程序,使用單點(diǎn)傳送,那么每個(gè)客戶(hù)程序都要要復制一份數據,如果,互聯(lián)網(wǎng)上有10000個(gè)客戶(hù)端要收看這個(gè)音樂(lè )會(huì ), 那么服務(wù)器程序通過(guò)Internet要傳送10000G的數據,這必然導致網(wǎng)絡(luò )阻塞,降低網(wǎng)絡(luò )的傳輸速度。
如果服務(wù)器程序要將同一信息發(fā)送給多個(gè)客戶(hù)端,那么服務(wù)器程序和客戶(hù)程序可以利用多點(diǎn)傳送(multicasting)方式進(jìn)行通信。多點(diǎn)傳送 就是服務(wù)程序對專(zhuān)用的多點(diǎn)傳送組的IP地址和端口發(fā)送一系列自尋址數據包,通過(guò)加入操作IP地址被多點(diǎn)傳送Socket注冊,通過(guò)這個(gè)點(diǎn)客戶(hù)程序可以接收 發(fā)送給組的自尋址包(同樣客戶(hù)程序也可以給這個(gè)組發(fā)送自尋址包),一旦客戶(hù)程序讀完所有要讀的自尋址數據包,那么可以通過(guò)離開(kāi)組操作離開(kāi)多點(diǎn)傳送組。
文章來(lái)源于領(lǐng)測軟件測試網(wǎng) http://kjueaiud.com/