美文网首页
Android之WIFI通信-P2P的WlanDirect分析

Android之WIFI通信-P2P的WlanDirect分析

作者: 锄禾豆 | 来源:发表于2022-02-21 10:22 被阅读0次

代码路径

7.1 
frameworks/base/wifi/java/android/net/wifi/p2p

详细分析

1.关键是socket通信
服务端
ServerSocket

ServerSocket serverSocket = new ServerSocket(port);
Socket client = serverSocket.accept();//等待客户端接入

InputStream inputstream = client.getInputStream();//读
OutputStream outputStream = client.getOutputStream();//写


客户端
Socket

Socket socket = new Socket();
socket.bind(null);
socket.connect((new InetSocketAddress(host, port)), SOCKET_TIMEOUT);

OutputStream outputStream = socket.getOutputStream();//写
InputStream inputStream = socket.getInputStream();//读


2.如果是socket通信,就是需要port和ip,怎么获取这些信息,才是关键?
注:port一般当面协商写死,可以不用关注
1)尝试连接
mWifiP2pManager.connect(channel, config, new ActionListener() {

            @Override
            public void onSuccess() {
                // WiFiDirectBroadcastReceiver will notify us. Ignore for now.
            }

            @Override
            public void onFailure(int reason) {
                
            }
        });//注意config 这里面带了需要连接的address和请求的方式WifiP2pConfig:
                WifiP2pConfig config = new WifiP2pConfig();
                config.deviceAddress = device.deviceAddress;//请求连接的address
                config.wps.setup = WpsInfo.PBC;
这里的回调onSuccess不能说明已经连接成功

2)真正的结果来自广播,主要关注广播:
WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION

if (WifiP2pManager.WIFI_P2P_CONNECTION_CHANGED_ACTION.equals(action)) {

    NetworkInfo networkInfo = (NetworkInfo) intent
                    .getParcelableExtra(WifiP2pManager.EXTRA_NETWORK_INFO);

    if (networkInfo.isConnected()) {
        // we are connected with the other device, request connection
        // info to find group owner IP
        mWifiP2pManager.requestConnectionInfo(channel, new WifiP2pManager.ConnectionInfoListener() {
                    @Override
                    public void onConnectionInfoAvailable(WifiP2pInfo info) {
                          boolean formed = info.groupFormed;//true 代表此局域网群建立成功
                          boolean owner  = info.isGroupOwner;//true 代表当前设备为群主
                          //如果是群主,代表是服务端,如果不是群主代表客户端
                          //客户端 就拿着群主的信息建立socket通信
                          //服务端 自己就直接建立socket等待连接
                        
                    }
                });//再次获取info进行校验,判断是否是group owner还是其他
    } else {
        // It's a disconnect
        
    }
    
3)怎么当群主呢?
通过mWifiP2pManager.createGroup创建

4)服务端的群主创建之后,怎么被发现?
客户端调用mWifiP2pManager.discoverPeers(channel, new WifiP2pManager.ActionListener() {

                    @Override
                    public void onSuccess() {
                        
                    }

                    @Override
                    public void onFailure(int reasonCode) {
                        
                    }
                });//真正的结果来自广播WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION
注意:
android.permission.ACCESS_FINE_LOCATION

5)WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION的处理业务:
if (WifiP2pManager.WIFI_P2P_PEERS_CHANGED_ACTION.equals(action)) {

    // request available peers from the wifi p2p manager. This is an
    // asynchronous call and the calling activity is notified with a
    // callback on PeerListListener.onPeersAvailable()
    if (manager != null) {
        manager.requestPeers(channel, new PeerListListener() {
                    @Override
                    public void onPeersAvailable(WifiP2pDeviceList peers) {
                        //获取真正的对等设备:peers.getDeviceList()
                        //这样我们来着这些对等设备就可以connect
                    }
                });
    }
}

6)整个过程都需要channel,也就是channel需要第一时间初始化:
mWifiP2pManager = (WifiP2pManager) getSystemService(Context.WIFI_P2P_SERVICE);
channel = mWifiP2pManager.initialize(this, getMainLooper(), new ChannelListener() {
            @Override
            public void onChannelDisconnected() {
                
            }
        });

初始化channel后,会接收到两个广播:
WifiP2pManager.WIFI_P2P_STATE_CHANGED_ACTION

// wifi p2p status.
int state = intent.getIntExtra(WifiP2pManager.EXTRA_WIFI_STATE, -1);
if (state == WifiP2pManager.WIFI_P2P_STATE_ENABLED) { 
    
} else {}

WifiP2pManager.WIFI_P2P_THIS_DEVICE_CHANGED_ACTION//本机WifiP2pDevice状态值
(WifiP2pDevice) intent.getParcelableExtra(
                    WifiP2pManager.EXTRA_WIFI_P2P_DEVICE)

总结

WifiP2pManager的调用都涉及回调,但是回调的价值又不是很大,因为仍配合使用了广播。

问题

1.为什么这么做呢?具体见详细的代码流程

2.生成群主的名字在哪里?是否可以自定义

3.什么时候初始化服务端?

补充

权限设置:
    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.READ_PHONE_STATE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />

参考学习

https://segmentfault.com/a/1190000037761166

http://www.edbiji.com/doccenter/showdoc/145/nav/1507.html

https://www.zhihu.com/question/46229570

https://developer.android.com/guide/topics/connectivity/wifip2p

https://www.jianshu.com/p/71d33f4373a7

https://github.com/leavesC/WifiP2P

https://www.jianshu.com/p/e9a23dfda330

https://juejin.cn/post/6844903736083480583

相关文章

网友评论

      本文标题:Android之WIFI通信-P2P的WlanDirect分析

      本文链接:https://www.haomeiwen.com/subject/jzwqkrtx.html