在 UDP 網絡編程中,發送方與接收方沒有建立聯系,沒有明顯的服務器端和客戶端的區別。
此類表示用來發送和接收數據報包的套接字。
主要的構造方法:
DatagramSocket():創建實例,綁定本機的默認IP地址,隨機選擇端口。通常用於客戶端編程,沒有特定監聽的端口,僅僅使用一個臨時的。
DatagramSocket(int port):創建實例,指定端口號,即固定監聽Port端口的報文。
DatagramSocket(int port, InetAddress localAddr):制定IP地址和端口號。當一台機器擁有多於一個IP地址的時候,由它創建的實例僅僅接收來自LocalAddr的報文。
常用方法:
receive(DatagramPacket d):接收數據報文到d中。
send(DatagramPacket d):發送報文d到目的地。
setSoTimeout(int timeout):設置超時時間,單位為毫秒。
close():關閉DatagramSocket。在應用程序退出的時候,通常會主動釋放資源,關閉Socket,但是由於異常地退出可能造成資源無法回收。所以,應該在程序完成時,主動使用此方法關閉Socket,或在捕獲到異常拋出後關閉Sock
用於處理報文,將byte數組、目標地址、目標端口等數據包裝成報文或者將報文拆卸成byte數組。
主要構造方法:
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數組。
常用方法:
getData():它從實例中取得報文的byte數組編碼。
發送端:
1.建立udpsocket服務端點。該端點建立,系統會隨機分配一個端口。如果不想隨機配置,可以手動指定。 DatagramSocket ds = new DatagramSocket(9999);此處制定端口為 9999,這個端口號是發送端的端口號。
2. 將數據進行packet包的封裝,必須要指定目的地址和端口。 byte[] buf = "hello,客戶端".getBytes(); DatagramPacket dp =new DatagramPacket(buf,buf.length,InetAddress.getByName("192.168.1.1"),9999);
3. 通過socket服務的send方法將該包發出。 ds.send(dp);
4. 將socket服務關閉。主要是關閉資源。 ds.close();
接收端:
1. 建立udp的socket服務。要監聽一個端口。 DatagramSocket ds = new DatagramSocket(9999);
2. 定義一個緩沖區,將該緩沖區封裝到packet包中。 byte[] buf = new byte[1024]; DatagramPacket dp = new DatagramPacket(buf,buf.length);
3. 通過socket的receive方法將數據存入數據包中。 ds.receive(dp);receive方法產生一個“阻塞”。
4. 通過數據包dp的方法getData()、getAddress()、getPort()等方法獲取包中的指定信息。
5. 關閉socket。 ds.close();
注意:1.在創建DatagramSocket類實例時,如果端口已經被使用,會產生一個SocketException的異常拋出,並導致程序非法終止,這個異常應該注意捕獲。
2.“阻塞”是一個專業名詞,它會產生一個內部循環,使程序暫停在這個地方,直到一個條件觸發。
接收端:
public class Server { public static void main(String[] args) throws IOException { //綁定本機IP,指定端口號為 9999. DatagramSocket server = new DatagramSocket(9999); //准備字節數組,大小可容納1024個字節開始接收數據。 byte[] bytes = new byte[1024]; //將字節數組中的前1024個字節封裝進 packet 中。 DatagramPacket packet = new DatagramPacket(bytes,1024); //通過socket的 receive()方法將數據存入數據包中。 server.receive(packet); //將服務器端接收到的數據打印出來,此時的數據已經解析成了原始的數據並且是實際接收到的長度 String Msg = new String(packet.getData(),0,packet.getLength()); System.out.println("服務器端接收到的消息" + Msg); } }
發送端:
public class Client { public static void main(String[] args) throws IOException { //綁定本機端口號,隨機選擇一個端口號 @SuppressWarnings("resource") DatagramSocket client = new DatagramSocket(); //向服務器端發送數據 String str = "Hello,I'm client"; //以字節形式發送 byte[] bytes = str.getBytes(); //將字節信息封裝在 packet 中以待發送。注意此時要獲得的參數有字節數組中從0 到結束的所有字節,接收端的IP地址和端口號。 DatagramPacket packet = new DatagramPacket(bytes,0,bytes.length,InetAddress.getByName("127.0.0.1"),9999); //發送 client.send(packet); } }
output:
注意,UDP通信過程中發段和收端不需要建立連接,主要通過 send()和receive()方法來發送和接受數據,並且發送和接收的數據均以 packet 為載體,發送的時候,packet 的參數應該有接收方的 IP地址(通過InetAddress.getByName()來獲取)和端口號。
如有不對之處,還望指正,謝謝(●'◡'●)