1、UDP接地氣解釋Q:
啥是UDP?
A:
UDP協定是使用者資料報協定,基于UDP的通信與基于TCP的通信不同,TCP講究可靠傳送,是一對一,而UDP是不提供可靠的保證,但是傳輸資訊更快。可以把UDP形象地比喻成學校廣播,在廣播台吼一聲,學校範圍内的人就能聽得到,而在學校範圍外的人就聽不到,這裡說的範圍呢,在計算機中就是IP和端口,你進了這個範圍就能收到廣播的資訊。
大概了解了原理,看一下會用到的類和方法吧!InetAddress類是IP位址封裝類,下圖是它的一些方法,有一定基礎的同學看這個應該一點都不吃力,傳進去的參數有ip位址、域名位址(網址)、計算機名,然後會傳回一個對象,這個對象就包含了計算機名和ip位址。
這裡還需要用到一個資料包(DatagramPacket)和資料包套接字(DatagramSocket),他們之間的關系可以用一個快遞的例子來描述一下。資料包就是一個你将要寄出去的快遞包裹,包裹裡面有東西(資料),有多少東西就是包裹的大小(這裡相當包長度),包裹上寫着寄去那個目的地的位址,端口就相當是你去那個快遞公司寄這個包裹。
包裹包好了,需要一個快遞小哥來取件啊,這裡的DatagramSocket充當一個快遞員的角色,這裡端口就決定了快遞小哥的機關了,你在哪家快遞公司下的單肯定是由這家公司的人來收件,這就對應了上面的包裹的端口。send和receive方法就是發送和接收資料包的方法了。
這裡使用得更多的是DatagramSocket的一個子類MulticastSocket(多點廣播),它繼承了DatagramSocket,是以它能使用DatagramSocket類的所有方法,并且它自己本身多了兩個方法,加入廣播組和離開廣播組,這裡出現了一個廣播組的概念,廣播組其實就是發廣播的地方,你可以比喻為發快遞的地方,他是資料包擷取與發送的來源,你的包裹都是從這裡拿和發送的。
這裡需要注意的一點是,發出廣播和接收廣播的主機位址必須位于同一個組内,位址範圍為224.0.0.0 ~ 224.255.255.255,也就是說發廣播的位址是有範圍的,這個位址呢并不代表某個特定主機的位置。加入到同一個組的主機可以在某個端口上廣播資訊,也可以在某個端口上接收資訊。
1、
實戰
有了上面的基礎,那就來一個小例子實戰一下:
public class Weather extends Thread { // 建立類。該類為多線程執行程式 String weather = "節目預報:八點有大型晚會,請收聽"; int port = 9898; // 定義端口 InetAddress iaddress = null; // 建立InetAddress對象 MulticastSocket socket = null; // 聲明多點廣播套接字 Weather() { // 構造方法 try { // 執行個體化InetAddress,指定發廣播的位址 iaddress = InetAddress.getByName("224.255.101.0"); socket = new MulticastSocket(port); // 執行個體化多點廣播套接字 socket.setTimeToLive(1); // 指定發送範圍是本地網絡 socket.joinGroup(iaddress); // 加入廣播組 } catch (Exception e) { e.printStackTrace(); // 輸出異常資訊 } } public void run() { // run()方法 while (true) { DatagramPacket packet = null; // 聲明DatagramPacket對象 byte data[] = weather.getBytes(); // 聲明位元組數組 // 将資料打包 packet = new DatagramPacket(data, data.length, iaddress, port); System.out.println(new String(data)); // 将廣播資訊輸出 try { socket.send(packet); // 發送資料 sleep(3000); // 線程休眠 } catch (Exception e) { e.printStackTrace(); // 輸出異常資訊 } } } public static void main(String[] args) { // 主方法 Weather w = new Weather(); // 建立本類對象 w.start(); // 啟動線程 } }
講解:首先指定廣播的位址(快遞公司位址),然後執行個體化多點廣播套接字(快遞員),然後加入廣播組(快遞員在快遞公司上班),當多點廣播套接字調用send()方法時,快遞員就把你的包裹發出去。好了再來看一下接收廣播的代碼:
public class Receive_1 extends Thread { int port = 9898; InetAddress group = null; // 建立InetAddress對象 MulticastSocket socket = null; // 聲明多點廣播套接字
public Receive_1() { try { group=InetAddress.getByName("224.255.101.0"); socket=new MulticastSocket(port); socket.joinGroup(group); } catch (UnknownHostException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }
public void run() { while(true) { byte data[]=new byte[1024]; DatagramPacket packet=null; packet=new DatagramPacket(data, data.length,group,port);//接收資料包 try { socket.receive(packet); String message=new String(packet.getData(),0,packet.getLength()); System.out.println("廣播發來的消息:"+message); } catch (IOException e) { e.printStackTrace(); } } } public static void main(String[] args) { Receive_1 receive=new Receive_1(); receive.start(); } }
接收廣播的也很簡單,加入廣播組就可接到廣播發來的資料包,然後把資料包中的資料拿出來就行了,注意:這裡的receive()方法接收資料時,如果還沒有可以接收的資料,它會阻塞,一直等到網絡上有資料傳來。來看一下效果吧!
總結:
發送資料包的步驟:
- 使用DatagramSocket()建立一個資料包套接字。
- 使用DatagramPacket(byte[] buf,int length,InetAddress,int port)建立要發送的資料包。
- 使用DatagramSocket類的send()方法發送資料包。
- 使用DatagramSocket(int port)建立資料包套接字,綁定到指定端口。
- 使用DatagramPacket(byte[] buf,int length)建立位元組數組來接收資料包。
- 使用DatagramSocket類的receive()方法接收資料包。