P2P架構介紹
P2P架構中定義了三個組件,一個設備,兩種角色。這三個組件分別是:
- P2P Device:它是P2P架構中角色的實體,讀者可把它當做一個Wi-Fi設備。
- P2P Group Owner(GO):P2P網絡建立時會產生一個Group。
- P2P Group Client(GC):
- 在組建P2P Group(即P2P Network)之前,智能終端都是一個一個的P2P Device。
- 當這些P2P Device設備之間完成P2P協商后,那么其中將有一個並且只能有一個Device來扮演GO的角色,而其他Device來扮演GC的角色。
最終構成的這個P2P Group組織結構如圖所示:
P2P Group示意圖
如圖展示了一個典型P2P Group的構成,其中:
一個P2P Group中只能有一個GO。一個GO可以支持1個或多個(即圖中的1:n)GC連接。
- 由於GO的功能類似於AP,所以周圍那些不支持P2P功能的WIFI STA也能發現並關聯到GO。這些WIFI STA被稱之為Legacy Clients。
注意:“不支持P2P功能”更准確的定義是指不能處理P2P協議。在P2P網絡中,GO等同於AP,所以Legacy Clients也能搜索到GO並關聯上它。不過,由於Legacy Clients不能處理P2P協議,所以P2P一些特有功能在這些Legacy Clients中無法實現。
Wifi_Direct的大致配對流程如下:

常見的問題
問題1:WifiP2pManger.connect()時,如何確定誰是GO,誰是GC
答:調用WifiP2pManger.connect()進行連接時,GO還算GC的身份是隨機的。開發者無法決定GroupOwner是哪台設備,但是可以通過WifiP2pConfig.groupOwnerIntent參數進行建議。
問題2:如果一定要確定誰是GO,誰是GC,怎么辦
答:第一步:GO端先調用WifiP2pManger.createGroup
第二步:GO端或者GC端調用WifiP2pManger.connect
即:先建立Group,再連接
問題3:如何斷開連接
答:WifiP2pManger.removeGroup
注意:WifiP2pManger.removeGroup是移除Group,斷開連接。WifiP2pManger.cancelConnect()斷開一個connecting的連接,即斷開當前狀態是Invited的連接。
問題4: 我們已知配對成功的前提條件是:進行配對的兩台設備都必須能夠掃描到對方。那么如何保證本機一直處於搜索狀態呢?
答:經過測試得知,一般情況下,本機Scan一次,能夠保持在線狀態3分鍾,即能夠搜索到其他設備/被其他設備搜索到的時間一般是3分鍾。但是這個3分鍾不是非常准確的,這跟手機性能或者WIFI芯片都有很大關系。因此我們能做的方案就是如果搜索結束,就重啟一次搜索。
對於一般的Peer Discovery而言,如果搜索結束,會收到廣播WifiP2pManager.WIFI_P2P_DISCOVERY_CHANGED_ACTION,這樣再收到廣播后重新搜索就可以。
對於Service Discovery而言(這其實是使用最廣泛的),搜索結束后,系統不會發出廣播通知,這樣就給開發者帶來一個難題:你無法知曉當前是否處於搜索(可見)狀態。
目前比較可行的做法是:每隔3分鍾(或者更短)重啟一次搜索,這樣基本保證本機一直處於搜索狀態。但是這僅能覆蓋大多數的情況,建議再此基礎上再加入手動搜索(搜不到可以讓用戶手動搜索)保證當前的可見狀態。
目前wifip2p依然不是很穩定,從測試的結果來說,Wifi_Direct的表現受具體設備的影響很大,配對的速度也有較大差異,從10秒到2分鍾甚至更久。有可能出現
a.A機器處於搜索(可見)狀態,但是B機器依然搜索不到;
b.還有可能出現A機器處於搜索(可見)狀態,B機器也搜索到了,但是連接失敗(此情況的主要原因還是因為A機器搜索結束后系統不發通知,而B機器當前搜索到的A機器是之前A機器的狀態)
問題5:如何把一個文件非常方便的發送給多個設備
答:
方法1:在一次一對一文件傳輸完畢后,直接斷開連接進行搜索/連接/傳輸,這樣就可以實現相同文件(夾)的多目標設備的發送。
方法2:使用問題2的答案,發送方做GO,接收方全部做GC,即可。
問題6:
我們知道
1.在進行connect的時候,連接兩端是GO還是GC是隨機的。
2.GC可以知道GO的地址,而GO是不知道GC的地址的.
3.一般的Socket編程思路是,GO做Server端,GC做Client端。
那么問題來了,如何能夠實現PeerA連接PeerB后,PeerA直接發送數據給PeerB呢?
答:方法一:使用問題2中的答案,先確定身份(誰是GO,誰是GC),再發送數據
方法二:步驟(假設PeerA是數據發送端,PeerB是數據接收端)
1.connect成功后,GO做server,GC做client
2.socket連接成功后,PeerA執行發送線程,PeerB執行接收線程
參考文章:
Android平台Wifi_Direct使用 http://blog.csdn.net/a220315410/article/details/9114653
《深入理解Android:Wi-Fi,NFC和GPS》 http://blog.csdn.net/innost/article/details/21555957