接地氣講解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()方法接收數據時,如果還沒有可以接收的數據,它會阻塞,一直等到網絡上有數據傳來。

總結:

發送數據包的步驟:

  1. 使用DatagramSocket()創建一個數據包套接字。
  2. 使用DatagramPacket(byte[] buf,int length,InetAddress,int port)創建要發送的數據包。
  3. 使用DatagramSocket類的send()方法發送數據包。

接收數據包的步驟:

  1. 使用DatagramSocket(int port)創建數據包套接字,綁定到指定端口。
  2. 使用DatagramPacket(byte[] buf,int length)創建位元組數組來接收數據包。
  3. 使用DatagramSocket類的receive()方法接收數據包。

感謝

之前一直聽說UDP協議,今天總算解開它的面紗了!