在线观看www成人影院-在线观看www日本免费网站-在线观看www视频-在线观看操-欧美18在线-欧美1级

您好,歡迎來電子發(fā)燒友網(wǎng)! ,新用戶?[免費(fèi)注冊(cè)]

您的位置:電子發(fā)燒友網(wǎng)>電子百科>通信技術(shù)>

基于Android完整UDP通信模塊的實(shí)現(xiàn)

2017年10月17日 15:32 作者: 用戶評(píng)論(0
關(guān)鍵字:Android(124886)UDP(33356)

  TCP與UDP有什么差異?Android 設(shè)備上,一個(gè)手機(jī)通過熱點(diǎn)連接另一個(gè)手機(jī)。這種場(chǎng)景下,完整的 UDP 通信模塊應(yīng)該考慮哪些方面,又應(yīng)該如何優(yōu)化。本文將圍繞這些問題展開描述。

  TCP與UDP差異對(duì)比分析,UDP 在 Java 中的使用

v

  我們都知道,開發(fā)一個(gè) Android 應(yīng)用程序,目前大多數(shù)還是使用的是 Java 語言。在 Java 語言中怎么去使用 UDP 協(xié)議呢?

  其實(shí) Socket 可以理解為對(duì) TCP、UDP 協(xié)議在程序使用層面的封裝,提供出一些 api 來供程序員調(diào)用開發(fā),這就是 Socket 最表層的含義。

  在 Java 中,與 UDP 相關(guān)的類有 DatagramSocket、DatagramPacket 等,關(guān)于他們的使用,這里不著重介紹。

  好了,假設(shè)大家對(duì)他們的使用都已大概了解,可以正式開始本文的內(nèi)容了。

  初始化一個(gè) UDPSocket

  首先創(chuàng)建一個(gè)叫 UDPSocket 的類。

基于Android完整UDP通信模塊的實(shí)現(xiàn)

  在構(gòu)造方法里,我們進(jìn)行下一些初始化操作,簡(jiǎn)單來說就是創(chuàng)建一個(gè)線程池,記錄一下當(dāng)前時(shí)間毫秒值,至于他們有什么用,再往下看:

 基于Android完整UDP通信模塊的實(shí)現(xiàn)

  這里我們首先創(chuàng)建了一個(gè) DatagramSocket 作為“客戶端”,其實(shí) UDP 本身沒有客戶端和服務(wù)端的概念,只有發(fā)送方和接收方的概念,我們把發(fā)送方暫時(shí)當(dāng)成是一個(gè)客戶端吧。

  創(chuàng)建 DatagramSocket 對(duì)象時(shí),傳入了一個(gè)端口號(hào),這個(gè)端口號(hào)可以在一個(gè)范圍內(nèi)自己定義,表示這個(gè) DatagramSocket 在此端口上監(jiān)聽數(shù)據(jù)。

  然后又創(chuàng)建了一個(gè) DatagramPacket 對(duì)象,作為數(shù)據(jù)的接收包。

  最后調(diào)用 startSocketThread 啟動(dòng)發(fā)送和接收數(shù)據(jù)的線程。

基于Android完整UDP通信模塊的實(shí)現(xiàn)

  首先 clientThread 線程的目的是調(diào)用 DatagramSocket receive 方法,因?yàn)?receive 方法是阻塞的,不能放在主線程,所以自然開啟一個(gè)子線程了。receiveMessage 就是處理接受到的 UDP 數(shù)據(jù)報(bào),我們先不看接受數(shù)據(jù)的這個(gè)方法,畢竟還沒人發(fā)消息呢,自然就談不上收了。

  心跳包保持“長(zhǎng)連接”

  來到本文的第一個(gè)重點(diǎn),我們都知道 UDP 本身沒有連接的概念。在 Android 端應(yīng)用 UDP 和 TCP 的場(chǎng)景是一個(gè)手機(jī)連接另一個(gè)手機(jī)的熱點(diǎn),二者處在同一局域網(wǎng)中。在二者并不知道對(duì)方的存在時(shí),怎么才能發(fā)現(xiàn)彼此呢?

  通過心跳包的方式,雙方都每隔一段時(shí)間發(fā)一個(gè) UDP 包,如果對(duì)方接收到了,那就能知道對(duì)方的 ip,建立起通信了。

基于Android完整UDP通信模塊的實(shí)現(xiàn)

  這段心跳的目的就是每隔十秒通過 sendMessage 發(fā)送一個(gè)消息,看看對(duì)方能不能收到。若對(duì)方收到消息,則刷新下 lastReceiveTime 的時(shí)間。

  這里我每隔十秒向?qū)Ψ桨l(fā)送了一個(gè)字符串。

基于Android完整UDP通信模塊的實(shí)現(xiàn)

  這里就是發(fā)送一個(gè)消息的代碼。最初在填寫 DatagramPacket 的參數(shù)之時(shí),我有一個(gè)疑問,那個(gè) targetAddress 其實(shí)是自己的 ip 地址。問題來了,我填寫了自己的 ip 地址和對(duì)方的端口,怎么可能找得到對(duì)方呢?你可能有一個(gè)疑惑 “192.168.43.255” 這個(gè)自己的 ip 地址是怎么來的,為什么要這么定義?

  首先 android 手機(jī)開啟熱點(diǎn),可以理解成一個(gè)網(wǎng)關(guān),有一個(gè)默認(rèn)的 ip 地址:“192.168.43.1”

  這個(gè) ip 地址不是我瞎編的一個(gè),在 Android 源碼之中,就是這么定義的:

  WifiStateMachine

 基于Android完整UDP通信模塊的實(shí)現(xiàn)

  所以我是知道所謂打開熱點(diǎn)一方的 ip 地址,而 UDP 發(fā)送消息時(shí)還有一個(gè)特性,就是發(fā)出去的消息,處在整個(gè)網(wǎng)關(guān)的設(shè)備是都可以接收到的,所以我自己的 ip 地址就定為了 “192.168.43.255”,所以這個(gè) ip 地址和 “192.168.43.1” 在同一網(wǎng)關(guān)中,你發(fā)送的消息,它是可以收到的。

  至于怎么判斷兩個(gè) ip 地址是否處在同一網(wǎng)段中:

  判斷兩個(gè)IP大小及是否在同一個(gè)網(wǎng)段中

  來做一個(gè)階段總結(jié):

  首先我們創(chuàng)建了一個(gè)發(fā)送端 DatagramSocket,啟動(dòng)了一個(gè)心跳程序,每間隔一段時(shí)間發(fā)送一個(gè)心跳包。

  因?yàn)槲抑罒狳c(diǎn)方的 ip 地址是默認(rèn)的 “192.168.43.1”,并且 UDP 的特性就是發(fā)送的消息同一網(wǎng)段的設(shè)備都可以收到。所以發(fā)送方的 ip 地址定為了與熱點(diǎn)一方處在同一網(wǎng)段的 “192.168.43.255”。

  事件與數(shù)據(jù)

  事件與數(shù)據(jù)這兩個(gè)模塊與業(yè)務(wù)就緊密相關(guān)了。

  先來說數(shù)據(jù),雙方發(fā)送的數(shù)據(jù)格式你們可以隨意定義,當(dāng)然我覺得還是定義成常規(guī)的 Json 格式就好。其中可以包含一些關(guān)鍵的事件字段:比如廣播心跳包、收到心跳包給對(duì)方上線的應(yīng)答包、超時(shí)的下線包、以及各種業(yè)務(wù)相關(guān)的數(shù)據(jù)等等。

  當(dāng)然發(fā)送數(shù)據(jù)時(shí)是轉(zhuǎn)換成二進(jìn)制數(shù)組發(fā)送的。發(fā)送中文字符、圖片等都沒有問題,但是可能有一些細(xì)節(jié)需要注意,隨時(shí) google 一下就好了。

  再來說下事件:

  與業(yè)務(wù)無關(guān)的事件有哪些?

  比如:

  DatagramSocket.send 方法之后就是發(fā)送數(shù)據(jù)成功的事件;

  DatagramSocket.receive 方法之后是數(shù)據(jù)接收成功的事件;

  在心跳包發(fā)送一段時(shí)間,仍沒有接到回信時(shí),是連接超時(shí)的事件;

  與業(yè)務(wù)相關(guān)的事件就和我們上文提到的數(shù)據(jù)類型有關(guān)了,設(shè)備上線,心跳包回應(yīng)等等。

  事件又如何發(fā)送出去,通知到各個(gè)頁面呢?用 Listener、或者其他事件總線的三方庫都沒問題,看你自己選擇了。

  處理接收的消息

 基于Android完整UDP通信模塊的實(shí)現(xiàn)

  理接收消息時(shí),有幾個(gè)值得注意的點(diǎn):

  receive 方法是阻塞的,沒收到數(shù)據(jù)包時(shí)會(huì)一直阻塞,所以要放到子線程中;

  每次接收到消息之后,重新調(diào)用 receivePacket.setLength;

  收到消息刷新lastReceiveTime的值,暫停心跳包的發(fā)送;

  處理收到的數(shù)據(jù)具體在業(yè)務(wù)上就是剛才我們談的發(fā)送數(shù)據(jù)的問題,視業(yè)務(wù)而定。

  “用戶”的概念

  上文已經(jīng)談過了 UDP 的特性,假如一個(gè)手機(jī)已經(jīng)開啟了熱點(diǎn),若多個(gè)手機(jī)與他相連接,則多個(gè)手機(jī)發(fā)送的消息它都可以收到。如果發(fā)送方的端口與接收方的端口相同的話,甚至自己發(fā)的消息,自己都可以收到。這就很尷尬了,也就是說我們既要剔除自己發(fā)給自己的消息,也得區(qū)分不同手機(jī)發(fā)來的消息,這個(gè)時(shí)候就理應(yīng)有一個(gè)“用戶”的概念。

  創(chuàng)建 User 對(duì)象,有哪些屬性可以看自己的業(yè)務(wù),本文的例子就有 ip、imei、以及 softversion。

基于Android完整UDP通信模塊的實(shí)現(xiàn)

  這里就不將所有的代碼展開來看了。如果有了手機(jī)的 imei 號(hào),那很容易就可以來做身份的區(qū)分,你既可以區(qū)分不同的發(fā)送方,也可以剔除掉自己發(fā)給自己的消息。當(dāng)然如果需要更多的信息,可以按照自己的業(yè)務(wù)區(qū)分,將這些信息作為發(fā)送的 messge,通過 Socket 發(fā)送。

非常好我支持^.^

(0) 0%

不好我反對(duì)

(0) 0%

( 發(fā)表人:黃昊宇 )

      發(fā)表評(píng)論

      用戶評(píng)論
      評(píng)價(jià):好評(píng)中評(píng)差評(píng)

      發(fā)表評(píng)論,獲取積分! 請(qǐng)遵守相關(guān)規(guī)定!

      ?
      主站蜘蛛池模板: 狠狠狠色丁香婷婷综合久久88 | 日本特黄特色特爽大片老鸭 | 黄色午夜网站 | 五月婷婷色 | 精品国产污网站在线观看15 | 亚洲视频在线一区二区三区 | 亚洲第一视频在线观看 | 黄到让你下面湿的视频 | 欧美高清milf在线播放 | 日韩精品一卡二卡三卡四卡2021 | 男女性gif抽搐出入 男女性高爱潮免费的国产 男女性高爱麻豆 | 欧洲亚洲一区 | 香蕉视频在线免费播放 | 激情五月婷婷小说 | 亚洲电影av | 无毒三级| 午夜毛片不卡高清免费 | 222www免费观看 | 欧美yw193.c㎝在线观看 | 复古毛片 | 久久久久久久久久久9精品视频 | 五月激情啪啪网 | 美剧免费在线观看 | 丁香五月网久久综合 | 午夜黄色剧场 | 高清视频一区二区 | 国产网站在线播放 | 72种姿势欧美久久久久大黄蕉 | 精品在线一区二区 | 人人干人人玩 | 性生生活三级视频在线观看 | 日本三级网站在线观看 | 免费看大美女大黄大色 | 一级a爱片久久毛片 | 欧美日韩一区不卡 | 婷婷五月天.com | 四虎影院大全 | 国产片一级特黄aa的大片 | 色多多在线看 | 四虎影院永久在线 | 欧美zooz人禽交免费观看 |