使用 UDP 在 Wifi Direct 上广播

using UDP to broadcast on Wifi Direct

我是 wifi direct 的新手,我希望能够广播消息,因为我有一个时间轴,当我单击 Post 按钮时,我希望所有连接的设备都显示该消息他们的时间表。我能够将数据发送到 peer.I 已经搜索过这个主题,我发现使用 UDP 是一个不错的选择,但我不知道如何在 wifi direct 中实现它。

我发现这段代码在 wifi 上使用 UDP 获取广播地址

InetAddress getBroadcastAddress() throws IOException {
WifiManager wifi = mContext.getSystemService(Context.WIFI_SERVICE);
DhcpInfo dhcp = wifi.getDhcpInfo();
// handle null somehow

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);} 

这用于发送和接收 UDP 广播数据包

DatagramSocket socket = new DatagramSocket(PORT);
socket.setBroadcast(true);
DatagramPacket packet = new DatagramPacket(data.getBytes(), data.length(),
getBroadcastAddress(), DISCOVERY_PORT);
socket.send(packet);

byte[] buf = new byte[1024];
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);

你能帮我解释一下它是如何工作的吗 提前致谢。

一种解决方案是将数据包多播到多播组。所有设备都加入一个多播 IP,发送方将数据包发送到该多播 IP。确保您分配的 IP 在多播 IP 范围内。在处理多播时,设备需要获取多播锁。请注意,由于多播基于 UDP,因此在传输中会出现一些错误。

AsyncTask Class 用于将接收数据包的设备:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;

import android.content.Context;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class ReceiverMulticastAsyncTask extends AsyncTask<Void, Integer ,String > {

    @Override
    protected String doInBackground(Void... params) {

        //Acquire the MulticastLock
        WifiManager wifi = (WifiManager)  getActivity().getSystemService(Context.WIFI_SERVICE);
        MulticastLock multicastLock = wifi.createMulticastLock("multicastLock");
        multicastLock.setReferenceCounted(true);
        multicastLock.acquire();

        //Join a Multicast Group
        InetAddress address=null;
        MulticastSocket clientSocket=null;
        try {
            clientSocket = new MulticastSocket(1212);
            address = InetAddress.getByName("224.0.0.1");
            clientSocket.joinGroup(address);
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();

        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();        
        }
        DatagramPacket packet=null;           
        byte[] buf = new byte[1024];
        packet = new DatagramPacket(buf, buf.length);
        //Receive packet and get the Data
        try {
            clientSocket.receive(packet);
            byte[] data = packet.getData();
            Log.d("DATA", data.toString()+"");

        } catch (Exception e) {
            e.printStackTrace();

        }
        multicastLock.release();

        try {
            clientSocket.leaveGroup(address);
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        clientSocket.close();
        return "";
    }

    @Override
    protected void onPostExecute(String result) {
        //do whatever...
    }
}

AsyncTask Class 用于将发送数据包的设备:

import java.io.IOException;
import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.SocketException;
import java.net.UnknownHostException;

import android.content.Context;
import android.net.wifi.WifiManager;
import android.net.wifi.WifiManager.MulticastLock;
import android.os.AsyncTask;
import android.util.Log;
import android.view.View;
import android.widget.TextView;

public class SenderMulticastAsyncTask extends AsyncTask<Void, Integer, String> {

    @Override
    protected String doInBackground(Void... params) {

        int port =1212;
        DatagramSocket socket=null;
        try {
            socket = new DatagramSocket(port);
        } catch (SocketException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        InetAddress group = null;
        try {
            group = InetAddress.getByName("224.0.0.1");
        } catch (UnknownHostException e) {
            // TODO Auto-generated catch block
            socket.close();
            e.printStackTrace();
        }

        //Sending to Multicast Group
        String message_to_send ="Test";
        byte[] buf = message_to_send.getBytes();
        DatagramPacket packet = new DatagramPacket(buf, buf.length, group, port);
        try {
            socket.send(packet);
            Log.d("Send", "Sending Packet");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            socket.close();
            e.printStackTrace();
        }

        socket.close();
        return "";
    }

    @Override
    protected void onPostExecute(String result) {
        //do whatever ...
    }
}

在Android的Wi-Fi P2P中有一个"group owner"的概念,就是作为接入点的设备。对于当前 API 组所有者的 IP 地址似乎设置为 192.168.49.1,我认为这是在某处进行了硬编码。快速猜测该组网络的广播地址为 192.168.49.255。到目前为止,我测试过的所有(少数)设备都是如此。