Udp網路編程
基於Tcp協議的網路通訊能夠建立可靠的串連,同時也將消耗大量的系統效能,為了減少系統開銷,在網路通訊中提供了UDP傳輸協議。UDP是不可靠的串連,廣泛應用於個中聊天工具中。
使用UDP協議發送資料,所有的資訊以資料報的形式發送,但用戶端不一定能夠接受成功。在Java中使用DatagramSocket類和DatagramPacket類實現Udp網路通訊。 一:DatagramSocket
DatagramSocket類
| 方法 |
類型 |
描述 |
| public DatagramSocket() |
構造方法 |
構造DatagramSocket對象不指定監聽連接埠 |
|
public DatagramSocket(int prot) |
構造方法 |
構造DatagramSocket對象指定監聽連接埠 |
| public void send(DatagramPacket p) |
構造方法 |
發送資料報 |
| public void receive(DatagramPacket p) |
方法 |
接受資料報 |
使用DatagramSocket類編寫發送程式,在構造DatagramSocket對象時若未指定連接埠號碼,系統將自動分配一個連接埠號碼。這就相當於店電話時,可以使用固話、小靈通、手機實現撥號。但對方的電話號碼是固定的,即接收程式必須指定一個連接埠號碼。 UDP 資料報通過資料通訊端 DatagramSocket 發送和接收, 系統不保證 UDP 資料報一定能夠安全送到目的地,也不能確定什麼時候可以抵達。 二:DatagramPacket
DatagramPacket類的主要方法
| 方法 |
類型 |
描述 |
| public DatagramPacket(byte[] buf,int length) |
構造方法 |
構造DatagramPacket對象時指定記憶體空間和大小 |
| public DatagramPacket(byte[] buf,int length,InetAddress address,int prot) |
構造方法 |
構造DatagramPacket對象時指定記憶體空間和大小、目標地址和連接埠 |
| public byte[] getData() |
方法 |
返回接收資料 |
| public int getLength() |
方法 |
返回傳送或接收資料的長度 |
| public InetAddress getAddress() |
方法 |
返回機器的地址 |
DatagramPacket 對象封裝了 UDP 資料報,在資料報中包含了發送端的 IP 地址和連接埠號碼以及接收端的 IP 地址和連接埠號碼。 UDP 協議中每個資料報都給出了完整的地址資訊,因此無須建立發送方和接收方的串連 三:InetAddress類
InetAddress主要方法
| 方法 |
類型 |
描述 |
| public static InetAddressgetByName(String host) |
方法 |
通過主機名稱或Ip地址獲得一個InetAddtess |
| public static String getHostName() |
方法 |
擷取Ip地址對應的主機名稱 |
| public String getHostAddress() |
方法 |
返回IP地址字串 |
InetAddress類用於表示電腦地址。 udp通訊流程 流程: 1. DatagramSocket與DatagramPacket 2. 建立發送端和接收端 3. 建立資料包 4.調用 Socket的發送、接收方法 5. 關閉Socket 編寫UDP網路程式需要分別編寫發送程式和接收程式。他們是兩個獨立的運行程式。 例一: 注意:先開接收端。(不想多說)
/** * 發送程式 * @throws IOException */@org.junit.Testpublic void send() throws IOException{//建立一個資料報DatagramSocket ds=new DatagramSocket();byte[] buf="hello world".getBytes();//建立一個資料包,每一個資料包不能大於64k,發送資料資訊(buf)發送到(哪。)IP(127.0.0.1)、連接埠號碼,(9090)DatagramPacket dp=new DatagramPacket(buf, 0, buf.length, InetAddress.getByName("127.0.0.1"),9090);ds.send(dp);ds.close();}/** * 接收程式 * @throws IOException */@org.junit.Testpublic void receive() throws IOException{DatagramSocket ds=new DatagramSocket(9090);byte[] buf=new byte[1024];DatagramPacket dp=new DatagramPacket(buf, 0, buf.length);//把資料報中的資料寫入到 dp中資料包中ds.receive(dp);System.out.println(new String(dp.getData(),0,dp.getLength()));ds.close();} 列印結果:hello world 例二:
/** * 發送程式 */@org.junit.Testpublic void UdpSend(){DatagramSocket ds=null;DatagramPacket dp=null;try {//ds用於完成訊息的發送ds=new DatagramSocket();String info="hello world";/** * 將待發的訊息封裝為DatagramPacket,DatagramPacket指定了訊息放鬆的目標主機地址及連接埠 */dp=new DatagramPacket(info.getBytes(), info.getBytes().length,InetAddress.getByName("localhost"),3000);ds.send(dp);} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}finally{ds.close();//訊息發送完畢後,關閉對象}}/** * 接收程式 */@org.junit.Testpublic void UdpReceive(){DatagramSocket ds=null;DatagramPacket dp=null;byte[] buf=new byte[1024];try {/** * (發送程式)發送資訊時,指定訊息發送的目標連接埠是3000,所以在接收程式中,要構建 * DatagramSocket對象時,連接埠號碼應與發送程式資料包中指定的連接埠號碼一致 */ds=new DatagramSocket(3000);//拿到3000連接埠的資料報dp=new DatagramPacket(buf, 1024);//建立一個資料包,接收發送程式傳遞的資料。ds.receive(dp);//把從3000連接埠的資料報資訊寫入(接收)到dp資料包中。String str=new String(dp.getData(),0,dp.getLength());str=str+" from "+dp.getAddress().getHostAddress();System.err.println(str);} catch (Exception e) {// TODO: handle exceptione.printStackTrace();}finally{ds.close();}}接收端列印結果:hello world from 127.0.0.1