天天看點

Android 指定網絡接口收發 Socket 資料

上次寫了一篇 Android Ping IPv6 位址的教程,這個工作的目的就是想通過 Volte 網絡發送 SIP 消息。但是 Android 預設的網絡環境是 Wifi、2G/3G/4G, 不會預設通過 Volte 網絡發送資料。是以需要通過一些方法來指定網絡接口。

指定網絡接口

首先介紹下 NetworkInterface 這個類

NetworkInterface 這個類表示由名稱組成的網絡接口和配置設定給這些網絡接口的 IP 位址清單。用于辨別所在多點傳播組的本地接口。

是以,Android 擷取所有網絡接口就可以通過 NetworkInterface 的 getNetworkInterfaces() 、 getInetAddress() 這個方法來實作

  • getNetworkInterfaces() 方法傳回本機上的所有接口。枚舉至少包含一個元素,可能隻顯示了一個本地回環接口。
  • getInetAddress() 方法傳回綁定某個網絡接口下的所有 IP 位址。

NetworkInterface.getNetworkInterfaces() 在調試中顯示的結果如下

Android 指定網絡接口收發 Socket 資料

調試資訊

圖中可以看出所有的網口清單,展開第一個顯示了它的一些屬性。其中 name 、 interfaceIndex 都是網絡接口的唯一辨別符号。

此時,如果我們需要指定網絡接口,就可以根據它的屬性來實作。

例子:擷取 rmnet_data7 網口的 IPv6 位址

// 擷取所有網口
List<NetworkInterface> interfaces = Collections.list(NetworkInterface.getNetworkInterfaces());
for(NetworkInterface iface : interfaces){
  if(iface.getDisplayName().equals("rmnet_data7")){ // 判斷網口名稱
    Enumeration<InetAddress> nifAddresses = iface.getInetAddresses();
    // 周遊 rmnet_data7 下所有 IP 位址
    while(nifAddresses.hasMoreElements()){
      InetAddress ni = nifAddresses.nextElement();
      Log.i("interface",ni.toString());
    }
  }
}

           

運作可以看到 log 中列印了 rmnet_data7 的 IP 位址

測試指定網口

接下來看看資料到底是不是通過這個網絡接口發送出去了。

我通過代碼建立了一個 TCP 連接配接,然後發送資料給 SIP 伺服器,由于這不是重點,我就不貼代碼了。

運作程式,通過 tcpdump 抓包後顯示發送成功,并抓到了傳回資料

Android 指定網絡接口收發 Socket 資料

wireshark

黑色标記行為發送資料, 橙色标記行為接收資料。

繼續閱讀