Socket廣播包經(jīng)常被用于局域網(wǎng)內(nèi)的兩臺(tái)設(shè)備之間互相發(fā)現(xiàn)和消息傳遞,在Android應(yīng)用開(kāi)發(fā)過(guò)程中,也經(jīng)常會(huì)遇到這樣的需求,例如:兩臺(tái)Android設(shè)備之間、Android與手環(huán)等智能硬件之間、Android與Windows電腦之間等等。
創(chuàng)新互聯(lián)公司是專業(yè)的辰溪網(wǎng)站建設(shè)公司,辰溪接單;提供網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作,網(wǎng)頁(yè)設(shè)計(jì),網(wǎng)站設(shè)計(jì),建網(wǎng)站,PHP網(wǎng)站建設(shè)等專業(yè)做網(wǎng)站服務(wù);采用PHP框架,可快速的進(jìn)行辰溪網(wǎng)站開(kāi)發(fā)網(wǎng)頁(yè)制作和功能擴(kuò)展;專業(yè)做搜索引擎喜愛(ài)的網(wǎng)站,專業(yè)的做網(wǎng)站團(tuán)隊(duì),希望更多企業(yè)前來(lái)合作!
本文主要介紹在Android中使用Socket開(kāi)發(fā)廣播包程序時(shí)需要注意的編程事項(xiàng),以及解決方法。
首先給出一段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ā)送廣播包
當(dāng)然,這個(gè)做Android開(kāi)發(fā)的人應(yīng)該都知道,不能在UI線程中執(zhí)行任何網(wǎng)絡(luò)訪問(wèn)相關(guān)的操作,由于廣播包的發(fā)送也屬于網(wǎng)絡(luò)操作,因此必須放到單獨(dú)的線程中執(zhí)行。
2. 廣播地址不建議使用“255.255.255.255”
上述代碼中,廣播包的目標(biāo)地址設(shè)置為了“255.255.255.255”,其實(shí),這并不是一種推薦的做法。
“255.255.255.255” 是一種受限的廣播地址,常用于在計(jì)算機(jī)不知道自己IP地址的時(shí)候發(fā)送,比如設(shè)備啟動(dòng)時(shí)向DHCP服務(wù)器索要地址等等,一般情況下,路由器不會(huì)轉(zhuǎn)發(fā)目標(biāo)為受限廣播地址的廣播包。
而且,有些路由器/Wi-Fi熱點(diǎn)不支持該廣播地址(例如:用Android手機(jī)做Wi-Fi熱點(diǎn)的時(shí)候),因此在程序中會(huì)出現(xiàn)“ENETUNREACH (Network is unreachable)”的異常,因此,為了保證程序成功發(fā)送廣播包,建議使用直接廣播地址,例如:當(dāng)前IP地址是 192.168.1.100,子網(wǎng)掩碼是 255.255.255.0 的情況下,廣播地址為:192.168.1.255,(具體的推算方法這里就不展開(kāi)了,可以參考計(jì)算機(jī)網(wǎng)絡(luò)相關(guān)書(shū)籍)。
那么,如何得到本網(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ù)即可得到正確的“廣播地址”,通過(guò)setAddress函數(shù)設(shè)置到DatagramPacket對(duì)象中即可。
3. Android設(shè)置為Wi-Fi熱點(diǎn)時(shí)的廣播地址
這是個(gè)比較大的坑,當(dāng)Android設(shè)備被設(shè)置為Wi-Fi熱點(diǎn)的時(shí)候,上面的函數(shù)得到的地址是"0.0.0.0",因此,我們需要探究當(dāng)Android設(shè)備被設(shè)置為Wi-Fi熱點(diǎn)的時(shí)候,它的IP地址究竟是多少?
有人研究了Android底層源碼發(fā)現(xiàn),當(dāng)Android設(shè)備被設(shè)置為Wi-Fi熱點(diǎn)的時(shí)候,其IP地址是hardcode寫(xiě)死在源碼中的,地址是:“192.168.43.1”,對(duì)應(yīng)的廣播地址是:"192.168.43.255"
為此,我們需要寫(xiě)個(gè)函數(shù)來(lái)判斷一下當(dāng)前Android手機(jī)是否處于Wi-Fi熱點(diǎn)模式下,如果是,則應(yīng)該使用上面給出的這個(gè)廣播地址,這里給出代碼示例:
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并沒(méi)有開(kāi)放判斷是否處于熱點(diǎn)模式的API,因此,我們需要通過(guò)反射的方式來(lái)得到,另外,注意添加權(quán)限:
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
4. 小結(jié)
本文涉及到的代碼被封裝到了一個(gè)Broadcaster.java的文件中,可以在博文最后的附件中下載,也可以從下面的地址下載:
https://github.com/Jhuster/Android/blob/master/Socket/Broadcaster.java
關(guān)于Android Socket發(fā)送廣播包的那些坑就總結(jié)到這里了,有任何疑問(wèn)或者建議歡迎留言或者來(lái)信lujun.hust@gmail.com交流,或者關(guān)注我的新浪微博 @盧_俊 獲取最新的文章和資訊。
分享題目:AndroidSocket發(fā)送廣播包的那些坑
轉(zhuǎn)載來(lái)源:http://chinadenli.net/article22/ppsocc.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供外貿(mào)網(wǎng)站建設(shè)、手機(jī)網(wǎng)站建設(shè)、軟件開(kāi)發(fā)、關(guān)鍵詞優(yōu)化、網(wǎng)頁(yè)設(shè)計(jì)公司、動(dòng)態(tài)網(wǎng)站
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)