Android模拟器无法接收UDP,但在手机上正常工作。

4

你好,我正在尝试连接到网络上的一个盒子。它上面有一个工作的UDP服务器。通过下面的代码,我能够与盒子通信并从我的手机发送/接收UDP数据包。然而,我无法弄清楚如何使用Android模拟器进行设置。我在Windows 8上阅读了很多StackOverflow以及其他论坛,但没有运气。

Android代码:

import java.net.DatagramPacket;
import java.net.DatagramSocket;
import java.net.InetAddress;

import android.os.Handler;
import android.util.Log;

public class udp implements Runnable {
    // Private variable
    private String IPServer = "10.0.2.2";           // For Emulator
    //private String IPServer = "255.255.255.255";  // For Phone
    private int portServer = 6286;
    private int portDestin = 4381;

    private InetAddress serverAddr;
    private InetAddress localAddr;
    private DatagramSocket socketSend;
    private DatagramSocket socketList;
    private DatagramPacket packetSend;
    private DatagramPacket packetList;
    private Handler uiHandler;

public udp(){
};

public void send() {

    // Retrieve the server name
    try {
        Log.d("UDP", "Creating InetAddress");
        serverAddr = InetAddress.getByName(IPServer);
    } catch (Exception e) {
        Log.e("UDP", "InetAddress Error:", e);
    }

    // Create UDP sockets
    try {
        Log.d("UDP", "Creating Sockets");
        socketSend = new DatagramSocket(portServer);
        socketList = new DatagramSocket(portDestin);
    }
    catch(Exception e) {
        Log.e("UDP", "DatagramSocket Error:", e);
    }

    // Sets socket to broadcast
    try {
        Log.d("UDP", "SetBroadcast");
        socketSend.setBroadcast(true);
    }
    catch(Exception e) {
        Log.e("UDP", "SetBroadcast Error:", e);
    }

    // Create UDP packets
    try {
        Log.d("UDP", "Creating packets");
        byte[] dataSend = new byte[32];
        byte[] dataRead = new byte[32];
        String msg = "Packet Broadcast";
        dataSend = msg.getBytes();
        packetSend = new DatagramPacket(dataSend, dataSend.length, serverAddr, portDestin);
        packetList = new DatagramPacket(dataRead, dataRead.length, serverAddr, portDestin);
    }
    catch(Exception e) {
        Log.e("UDP", "DatagramPacket Error:", e);
    }

    // Send packet
    try {
        Log.d("UDP", "Sending packet");
        socketSend.send(packetSend);
    }
    catch(Exception e) {
        Log.e("UDP", "Send Error:", e);
    }

    // Receive packet
    Log.d("UDP", "Receiving packet");
    for(int i=0; i<2; i++)
    {
        try {
            socketList.receive(packetList);
        }
        catch(Exception e) {
            Log.e("UDP", "Receive Error:", e);
        }
        String packetRec = new String(packetList.getData());
        Log.d("UDP", "Received: "+packetRec);
    }       

    socketSend.close();
    socketList.close();
}

@Override
public void run() {
    // TODO Auto-generated method stub
}   
}

我需要向整个网络广播;这就是为什么我使用255.255.255.255,但对于安卓系统,我读到它不起作用,所以我打开模拟器中的设置,并找到我的IP地址如上面所述。

我还进行了端口重定向。

telnet localhost 5554
redir add udp:4381:4381

来自手机的日志:

02-11 12:01:09.743: D/UDP(17253): Creating InetAddress
02-11 12:01:09.743: D/UDP(17253): Creating Sockets
02-11 12:01:09.753: D/UDP(17253): SetBroadcast
02-11 12:01:09.753: D/UDP(17253): Creating packets
02-11 12:01:09.753: D/UDP(17253): Sending packet
02-11 12:01:09.753: D/UDP(17253): Receiving packet
02-11 12:01:09.753: D/UDP(17253): Received: Packet Broadcast????????????
02-11 12:01:09.763: D/UDP(17253): Received: ??????PACKETSTUFF???????????fP*

来自Android模拟器的日志:

02-11 20:00:22.742: D/UDP(1201): Creating InetAddress
02-11 20:00:22.742: D/UDP(1201): Creating Sockets
02-11 20:00:22.752: D/UDP(1201): SetBroadcast
02-11 20:00:22.772: D/UDP(1201): Creating packets
02-11 20:00:22.772: D/UDP(1201): Sending packet
02-11 20:00:22.772: D/UDP(1201): Receiving packet
02-11 20:00:22.772: D/UDP(1201): Received: Packet Broadcast????????????????????

感谢您的提前帮助!
更新:
我目前已经让我的模拟器使用UDP转发器NetworkActiv AUTAPF发送数据包到主机外部。它可以发送我的UDP数据包,但是无法将响应转发回来。有没有人知道我应该将响应发送到哪里?
2个回答

3

无法直接将Android模拟器连接到网络上的任何物理设备。

Android模拟器创建自己的局域网,每个模拟器实例都有一个新的局域网实例,具有相同的IP地址(这是可以的,因为它们不能彼此访问)。

如果您坚持使用模拟器与盒子通信,则应在计算机上创建一个UDP代理套接字(使用JAVA、C#、C++、VB或您想要的任何桌面编程语言)。

您的桌面应用程序工作方式:

  • 获取您的局域网子网以便稍后确定数据包源。
  • 为您的服务器使用的端口启动UDP监听器。
  • 查找发送方的IP地址(有API可用),如果发送方是模拟器,则将该数据包重新发送到使用盒子IP的盒子。

Android开发者网站上有一个关于此主题的很好的演示,请查看这里

祝你好运!


1
有没有一个Windows应用程序可以为我完成这个任务? - Jareddlc
有很多例子,只需使用任何Java示例并在您的PC上运行即可。 - Mr.Me
这是我可以使用的东西吗?http://www.softpedia.com/get/Network-Tools/Misc-Networking-Tools/Simple-UDP-Proxy-Pipe.shtml - Jareddlc
你知道我怎么才能找到发送者的IP地址吗(有API可以做到),如果发送者是模拟器? - Jareddlc

2

我曾经遇到过同样的问题,后来发现这是由于Android模拟器重定向和一个bug导致的。

首先,如果你使用API级别为25+的Android模拟器设备,你需要在不启用"AndroidWifi"功能的情况下启动设备,否则由于此bug,你将无法与设备通信。

具体操作如下:

cd "C:\Program Files (x86)\Android\android-sdk\emulator"
emulator.exe -avd <name+of+your+device> -feature -Wifi

接下来,您需要将本地主机的所需端口重定向到模拟器设备

telnet localhost 5554
auth <your+code+here>
redir add udp:<origin+port>:<destination+port>

最后,您需要将来自本地IP地址(192.168.1.X)的UDP数据包重定向到本地主机(127.0.0.1),否则模拟设备将无法接收该数据包。为此,您可以创建一个简单的UDP重定向器,或使用我创建的程序执行相同的操作 https://github.com/danidis91/Port-forward-UDP


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接