gpt4 book ai didi

android - 发送广播 UDP 但在其他 Android 设备上不接收

转载 作者:IT老高 更新时间:2023-10-28 23:32:47 26 4
gpt4 key购买 nike

我正在尝试开发一个应用程序来发送一些广播消息并从其他 android 设备接收一些答案。我在接收来自其他设备的 UDP 消息时遇到了一些问题。我应该提到,这段代码在 Gingerbread 上有效,但在 JellyBean 上它不再有效,我不知道可能是什么问题。

这里是我发送广播消息的地方(我知道其他设备监听端口 5000):

 private void sendUDPMessage(String msg) {

try {
DatagramSocket clientSocket = new DatagramSocket();

clientSocket.setBroadcast(true);
InetAddress address = InetAddress.getByName(Utils.getBroadcastAddress());

byte[] sendData;

sendData = msg.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData,
sendData.length, address, 5000);
clientSocket.send(sendPacket);

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

}

这是我收到它的地方:

private void start_UDP()
{
try {
serverSocketUDP = new DatagramSocket(5000);
}
catch (Exception e) {

Log.i(LOGTAG, "Exception opening DatagramSocket UDP");
}

final byte[] receiveData = new byte[1024];


while(runningUDP) {
Log.d(LOGTAG, "Waiting for Broadcast request in ServerUDP.");

final DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);

serverSocketUDP.receive(receivePacket);


byte[] sendData = new byte[1024];
InetAddress address = receivePacket.getAddress();
int port = receivePacket.getPort();
if(!receivePacket.getAddress().getHostAddress().equals(Utils.getLocalIpAddress()))
{
String req = new String(receivePacket.getData(), 0, receivePacket.getLength());


Log.d(LOGTAG, "Received UDP message : "+req+" from: "+receivePacket.getAddress().getHostAddress());
}
}// while ends
}//method ends

我应该提到,这 2 个函数在 2 个不同的线程中是分开的,所以我可以同时发送和接收。

我还获得了以下锁:

    powerManager =(PowerManager)context.getSystemService(Context.POWER_SERVICE);
wakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK ,LOGTAG); // PARTIAL_WAKE_LOCK Only keeps CPU on
wifiManager = (WifiManager)context.getSystemService(Context.WIFI_SERVICE);
wifiLock = wifiManager.createWifiLock(3, LOGTAG);
multicastLock = wifiManager.createMulticastLock(LOGTAG);

wakeLock.acquire();
multicastLock.acquire();
wifiLock.acquire();

以及 Manifest 文件的权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.WRITE_SETTINGS"/>
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE"/>

我已经测试了消息是否使用wireshark和tcpdump发送并且它们被发送。而且,更奇怪的是,我收到了我发送的广播消息(但我丢弃了它们,因为我不需要处理自己发送的消息)但我没有收到从其他设备发送的广播消息(应该有格式相同,只是源地址和包含的消息不同,任何一种方式都不会影响广播消息)。

如果您有任何想法,请告诉我,因为我真的没有其他可以尝试的方法了。任何帮助,将不胜感激。谢谢!

编辑:我已经进行了一些测试,即使当我在每部手机上运行 ifconfig wlan0 时,它也会显示类似

  ifconfig wlan0
wlan0: ip 169.254.17.28 mask 255.255.0.0 flags [up broadcast multicast]

这意味着接口(interface)处于 Activity 状态并且IP已设置并且可以接收广播消息和多播消息但是当我使用时

                 InetAddress in=InetAddress.getByName("169.254.17.28");
if (in.isReachable(1000))
Log.i(LOGTAG, "host is reachable");
else
Log.i(LOGTAG, "host is not reachable");

它在日志中显示主机不可访问。

这是我打开 Wi-fi 的地方

    private void startWifiAdhoc() {

WifiManager wifiManager = (WifiManager)SharingFileService.context.getSystemService(Context.WIFI_SERVICE);
String command="";
if (condWifiAdhoc == false) {

condWifiAdhoc=true;
wifiInterface = Utils.getWifiInterface();


wifiManager.setWifiEnabled(true);
localIP = Utils.getLinkLocalAddress();
}
else
{
wifiManager.setWifiEnabled(true);
localIP = Utils.getLinkLocalAddress();
}
// Set wifi ad-hoc
command = context.getFilesDir().getPath()
+ "/iwconfig " + wifiInterface + " mode ad-hoc essid "
+ "mcp" + " channel " + "1" + " commit\n";

Log.i(LOGTAG, command);
Utils.rootExec(command);


Log.i(LOGTAG, "Ip address used :" + localIP);
command = context.getFilesDir().getPath()
+ "/ifconfig " + wifiInterface + " " + localIP
+ " netmask 255.255.0.0 up\n";



Log.i(LOGTAG, command);
Utils.rootExec(command);

}

最佳答案

我通过使用此处描述的方法来计算广播地址来完成这项工作:https://code.google.com/p/boxeeremote/wiki/AndroidUDP

这是我的接收器:

try {
//Keep a socket open to listen to all the UDP trafic that is destined for this port
socket = new DatagramSocket(Constants.PORT, InetAddress.getByName("0.0.0.0"));
socket.setBroadcast(true);

while (true) {
Log.i(TAG,"Ready to receive broadcast packets!");

//Receive a packet
byte[] recvBuf = new byte[15000];
DatagramPacket packet = new DatagramPacket(recvBuf, recvBuf.length);
socket.receive(packet);

//Packet received
Log.i(TAG, "Packet received from: " + packet.getAddress().getHostAddress());
String data = new String(packet.getData()).trim();
Log.i(TAG, "Packet received; data: " + data);

// Send the packet data back to the UI thread
Intent localIntent = new Intent(Constants.BROADCAST_ACTION)
// Puts the data into the Intent
.putExtra(Constants.EXTENDED_DATA_STATUS, data);
// Broadcasts the Intent to receivers in this app.
LocalBroadcastManager.getInstance(this).sendBroadcast(localIntent);
}
} catch (IOException ex) {
Log.i(TAG, "Oops" + ex.getMessage());
}

这是我的发件人:

    public void sendBroadcast(String messageStr) {
// Hack Prevent crash (sending should be done using an async task)
StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build();
StrictMode.setThreadPolicy(policy);

try {
//Open a random port to send the package
DatagramSocket socket = new DatagramSocket();
socket.setBroadcast(true);
byte[] sendData = messageStr.getBytes();
DatagramPacket sendPacket = new DatagramPacket(sendData, sendData.length, getBroadcastAddress(), Constants.PORT);
socket.send(sendPacket);
System.out.println(getClass().getName() + "Broadcast packet sent to: " + getBroadcastAddress().getHostAddress());
} catch (IOException e) {
Log.e(TAG, "IOException: " + e.getMessage());
}
}

InetAddress getBroadcastAddress() throws IOException {
WifiManager wifi = (WifiManager) 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);
}

关于android - 发送广播 UDP 但在其他 Android 设备上不接收,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17308729/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com