91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Android Socket 發送廣播包的那些坑

發布時間:2020-06-21 20:59:01 來源:網絡 閱讀:10261 作者:Jhuster 欄目:移動開發

Socket廣播包經常被用于局域網內的兩臺設備之間互相發現和消息傳遞,在Android應用開發過程中,也經常會遇到這樣的需求,例如:兩臺Android設備之間、Android與手環等智能硬件之間、Android與Windows電腦之間等等。


本文主要介紹在Android中使用Socket開發廣播包程序時需要注意的編程事項,以及解決方法。


首先給出一段Android發送廣播包的示例代碼:


DatagramSocket socket = new DatagramSocket(8000);
socket.setBroadcast(true);
InetAddress addr = InetAddress.getByName("255.255.255.255");
byte[] buffer = "Hello World".getBytes();
DatagramPacket packet = new DatagramPacket(buffer,buffer.length);
packet.setAddress(addr);
packet.setPort(8086);
socket.send(packet);


下面分析其中需要注意的地方:


1. 不要在主線程中發送廣播包


當然,這個做Android開發的人應該都知道,不能在UI線程中執行任何網絡訪問相關的操作,由于廣播包的發送也屬于網絡操作,因此必須放到單獨的線程中執行。


2. 廣播地址不建議使用“255.255.255.255”


上述代碼中,廣播包的目標地址設置為了“255.255.255.255”,其實,這并不是一種推薦的做法。


“255.255.255.255” 是一種受限的廣播地址,常用于在計算機不知道自己IP地址的時候發送,比如設備啟動時向DHCP服務器索要地址等等,一般情況下,路由器不會轉發目標為受限廣播地址的廣播包。


而且,有些路由器/Wi-Fi熱點不支持該廣播地址(例如:用Android手機做Wi-Fi熱點的時候),因此在程序中會出現“ENETUNREACH (Network is unreachable)”的異常,因此,為了保證程序成功發送廣播包,建議使用直接廣播地址,例如:當前IP地址是 192.168.1.100,子網掩碼是 255.255.255.0 的情況下,廣播地址為:192.168.1.255,(具體的推算方法這里就不展開了,可以參考計算機網絡相關書籍)。


那么,如何得到本網段的直接廣播地址呢,下面是stackoverflow上面有位大牛分享的代碼:


public static InetAddress getBroadcastAddress(Context context) throws UnknownHostException {
    WifiManager wifi = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
    DhcpInfo dhcp = wifi.getDhcpInfo();
    if(dhcp==null) {
        return InetAddress.getByName("255.255.255.255");
    }
    int broadcast = (dhcp.ipAddress & dhcp.netmask) | ~dhcp.netmask;
    byte[] quads = new byte[4];
    for (int k = 0; k < 4; k++)
        quads[k] = (byte) ((broadcast >> k * 8) & 0xFF);
    return InetAddress.getByAddress(quads);
}


直接使用該函數即可得到正確的“廣播地址”,通過setAddress函數設置到DatagramPacket對象中即可。


3. Android設置為Wi-Fi熱點時的廣播地址


這是個比較大的坑,當Android設備被設置為Wi-Fi熱點的時候,上面的函數得到的地址是"0.0.0.0",因此,我們需要探究當Android設備被設置為Wi-Fi熱點的時候,它的IP地址究竟是多少?


有人研究了Android底層源碼發現,當Android設備被設置為Wi-Fi熱點的時候,其IP地址是hardcode寫死在源碼中的,地址是:“192.168.43.1”,對應的廣播地址是:"192.168.43.255"


為此,我們需要寫個函數來判斷一下當前Android手機是否處于Wi-Fi熱點模式下,如果是,則應該使用上面給出的這個廣播地址,這里給出代碼示例:


protected static Boolean isWifiApEnabled(Context context) {
    try {
        WifiManager manager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);  
        Method method = manager.getClass().getMethod("isWifiApEnabled");
        return (Boolean)method.invoke(manager);
    }
    catch (NoSuchMethodException e) {
        e.printStackTrace();
    }
    catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e)  {
        e.printStackTrace();
}
    return false;
}


Android SDK并沒有開放判斷是否處于熱點模式的API,因此,我們需要通過反射的方式來得到,另外,注意添加權限: 


<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />


4. 小結


本文涉及到的代碼被封裝到了一個Broadcaster.java的文件中,可以在博文最后的附件中下載,也可以從下面的地址下載:


https://github.com/Jhuster/Android/blob/master/Socket/Broadcaster.java


關于Android Socket發送廣播包的那些坑就總結到這里了,有任何疑問或者建議歡迎留言或者來信lujun.hust@gmail.com交流,或者關注我的新浪微博 @盧_俊 獲取最新的文章和資訊。



向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

白山市| 东明县| 达州市| 青海省| 恩施市| 惠州市| 长沙市| 西平县| 佳木斯市| 丰镇市| 乾安县| 穆棱市| 涞水县| 汉阴县| 周宁县| 凤山市| 平武县| 新沂市| 阜平县| 黄浦区| 钟祥市| 曲靖市| 贡山| 集贤县| 平果县| 综艺| 蒙城县| 荆州市| 郸城县| 梁山县| 重庆市| 台北市| 青铜峡市| 哈巴河县| 马关县| 南澳县| 芜湖市| 阿图什市| 淅川县| 内江市| 涿州市|