真实的国产乱ⅩXXX66竹夫人,五月香六月婷婷激情综合,亚洲日本VA一区二区三区,亚洲精品一区二区三区麻豆

成都創(chuàng)新互聯(lián)網(wǎng)站制作重慶分公司

AndroidSocket發(fā)送廣播包的那些坑-創(chuàng)新互聯(lián)

Socket廣播包經(jīng)常被用于局域網(wǎng)內(nèi)的兩臺設(shè)備之間互相發(fā)現(xiàn)和消息傳遞,在Android應用開發(fā)過程中,也經(jīng)常會遇到這樣的需求,例如:兩臺Android設(shè)備之間、Android與手環(huán)等智能硬件之間、Android與Windows電腦之間等等。

創(chuàng)新互聯(lián)堅持“要么做到,要么別承諾”的工作理念,服務(wù)領(lǐng)域包括:網(wǎng)站設(shè)計制作、成都網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣等服務(wù),滿足客戶于互聯(lián)網(wǎng)時代的桃江網(wǎng)站設(shè)計、移動媒體設(shè)計的需求,幫助企業(yè)找到有效的互聯(lián)網(wǎng)解決方案。努力成為您成熟可靠的網(wǎng)絡(luò)建設(shè)合作伙伴!

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

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

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. 不要在主線程中發(fā)送廣播包

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

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

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

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

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

那么,如何得到本網(wǎng)段的直接廣播地址呢,下面是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);
}

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

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

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

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

為此,我們需要寫個函數(shù)來判斷一下當前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,因此,我們需要通過反射的方式來得到,另外,注意添加權(quán)限:

4. 小結(jié)

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

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

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

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機、免備案服務(wù)器”等云主機租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應用場景需求。


標題名稱:AndroidSocket發(fā)送廣播包的那些坑-創(chuàng)新互聯(lián)
瀏覽地址:http://weahome.cn/article/csjjhs.html

其他資訊

在線咨詢

微信咨詢

電話咨詢

028-86922220(工作日)

18980820575(7×24)

提交需求

返回頂部