接地氣講解UDP協議和網絡程序設計(深度好文)
- 2019 年 11 月 8 日
- 筆記
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類的所有方法,並且它自己本身多了兩個方法,加入廣播組和離開廣播組,這裡出現了一個廣播組的概念,廣播組其實就是發廣播的地方,你可以比喻為發快遞的地方,他是數據包獲取與發送的來源,你的包裹都是從這裡拿和發送的。

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()方法接收數據包。
感謝
之前一直聽說UDP協議,今天總算解開它的面紗了!