2015-04-17 99 views
3

我是新来的wifi直接,我希望能够广播消息,因为我有一个时间表,当我点击发布按钮,我希望所有连接的设备都显示该消息在他们的时间表上。我能够发送数据点对点。我已经搜索了这个问题,我发现使用UDP是一个不错的选择,但我不知道如何实现它在WiFi直接。使用UDP在Wifi Direct上广播

我发现这个代码,使用UDP Wi-Fi以获取广播地址

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

能否请你帮我,给我解释一下它如何工作 在此先感谢。

+0

我有一个解决方案,您可以将数据包组播到多播组。所以如果所有的设备都加入了一个组播IP。然后发送一个UDP数据包到该组播IP将被所有设备接收。如果您希望我详细说明,请告诉我。 –

+0

@ZiadHalabi是的请详细说明,如果你的代码给出了一些很好的示例代码 – lna1994

+0

@ Ina1994请编辑你的问题,以便它在WiFi Direct中询问更广泛的广播问题。 –

回答

1

一种解决方案是将数据包组播到组播组。所有设备加入一个组播IP,并且发送者将数据包发送到该组播IP。确保您分配的IP属于多播IP的范围。在处理多播时,设备需要获取多播锁。请注意,由于Multicast基于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 ... 
    } 
} 
+0

我不明白我怎么可以实现这个代码在WiFi直接 – lna1994

+0

我的意思是'wifi'变量的类型'WifiManager'不'WifiP2pManager',我不能使用'的类型为'WifiP2pManager'的createMulticastLock' – lna1994

+0

建立WiFi Direct连接可以执行这些AsyncTask类。当建立WiFi Direct连接时,设备和组所有者之间的关系与处理接入点时的相同。例如在一个按钮监听器中,你可以写下这个:new SenderMulticastAsyncTask.execute(); –

3

在Android中的Wi-Fi P2P有一个“组所有者”的概念,它是充当接入点的设备。对于当前API,群组所有者的IP地址似乎设置为192.168.49.1,我认为这是硬编码的地方。有关该组网络的广播地址的快速猜测将为192.168.49.255。对于我已经测试过的所有(少数)设备,事实证明是这样。