【问题标题】:using UDP to broadcast on Wifi Direct使用 UDP 在 Wifi Direct 上广播
【发布时间】:2015-06-24 11:43:29
【问题描述】:

我是 wifi direct 的新手,我希望能够广播消息,因为我有一个时间线,当我单击发布按钮时,我希望所有连接的设备都在其时间轴上显示该消息。我能够点对点发送数据。我已经搜索过这个主题,我发现使用 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 发送一个 UDP 数据包将被所有设备接收。如果您希望我详细说明,请告诉我。
  • @ZiadHalabi 是的,请详细说明,如果您的代码提供一些示例代码会很棒
  • @Ina1994 请编辑您的问题,以便在 WiFi Direct 中提出更一般的广播问题。

标签: android wifi-direct broadcasting


【解决方案1】:

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

将接收数据包的设备的 AsyncTask 类:

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 类:

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 ...
    }
}

【讨论】:

  • 我不明白如何在 wifi direct 中实现此代码
  • 我的意思是wifi 变量的类型是WifiManager 而不是WifiP2pManager,我不能使用createMulticastLock 类型为WifiP2pManager
  • 建立 WiFi Direct 连接后,您可以执行这些 AsyncTask 类。建立 WiFi Direct 连接后,设备与组所有者之间的关系与处理接入点时的关系相同。例如在按钮监听器中,你可以这样写: new SenderMulticastAsyncTask.execute();
【解决方案2】:

在 Android 的 Wi-Fi P2P 中有一个“群主”的概念,即充当接入点的设备。对于当前的 API,组所有者的 IP 地址似乎设置为 192.168.49.1,我认为它在某处是硬编码的。快速猜测该组网络的广播地址将是 192.168.49.255。到目前为止,我测试过的所有(少数)设备都是这种情况。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-08-02
    • 2017-02-18
    • 1970-01-01
    • 2021-08-03
    • 1970-01-01
    相关资源
    最近更新 更多