Android从不接收UDP数据包

发布于 2024-08-18 03:49:16 字数 4357 浏览 2 评论 0原文

下面的代码会导致超时。

它在非 Android Java 上运行良好。怎么了?

 //@Override
public static void run()
{
    //System.out.println ( "Local Machine IP : "+addrStr.toString (  )  ) ;
    HelloWorldActivity.tv.setText("Trace 1");

    try
    {
        // Retrieve the ServerName
        InetAddress serverAddr; //= InetAddress.getByName(Server.SERVERIP);
        InetAddress ias[] = InetAddress.getAllByName(Server.SERVERNAME);
        serverAddr  = ias[0];

        Log.d("UDP", "C: Connecting...");
        /* Create new UDP-Socket */
        DatagramSocket socket = new DatagramSocket();

        /* Prepare some data to be sent. */
        String strQuery="ÿÿÿÿgetservers"+" "+Server.iProtocol+" "+"'all'";
        Log.d("UDP", strQuery);
        //byte[] buf = ("ÿÿÿÿgetservers 68 'all'").getBytes();
        byte[] buf = strQuery.getBytes();

        /* Create UDP-packet with
         * data & destination(url+port) */
        DatagramPacket packet = new DatagramPacket(buf, buf.length,
                                                   serverAddr, Server.SERVERPORT);

        Log.d("UDP", "C: Sending: '" + new String(buf) + "'");

        /* Send out the packet */
        socket.setSoTimeout(5000);
        socket.send(packet);
        Log.d("UDP", "C: Sent.");
        Log.d("UDP", "C: Done.");

        // http://code.google.com/p/android/issues/detail?id=2917

        byte[] buffer= new byte[1024*100];
        DatagramPacket receivePacket
          = new DatagramPacket(buffer,
                               buffer.length); //, serverAddr, Server.SERVERPORT);
        socket.receive(receivePacket);
        HelloWorldActivity.tv.setText("TTT");

        String x = new String(receivePacket.getData());
        Log.d("UDP", "C: Received: '" + x  + "'");
        HelloWorldActivity.tv.setText(x);

   } catch (Exception e) {
       HelloWorldActivity.tv.setText(e.getMessage());
       Log.e("UDP", "C: Error", e);
   }
}


public class Server
{
    /*
    //public static java.lang.string SERVERIP;
    public static String SERVERNAME = "monster.idsoftware.com";
    public static String SERVERIP = "192.246.40.56";
    public static int SERVERPORT = 27950;
    public static int PROTOCOL = 68;
      */

    //public static String SERVERNAME="monster.idsoftware.com";
    public static String SERVERNAME="dpmaster.deathmask.net";

    public static String SERVERIP="192.246.40.56";
    public static int SERVERPORT=27950;
    //public static int iProtocol= 68; // Quake3
    public static int iProtocol=71; // OpenArena

}

安卓清单:

<?xml version="1.0" encoding="utf-8"?>

<use-permission id="android.permission.READ_CONTACTS" />

    <use-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_GPS" />
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
    <uses-permission android:name="android.permission.ACCESS_CELL_ID" />

    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

<application
        android:icon="@drawable/icon"
        android:label="AAA New Application"
        >
    <activity android:name="HelloWorldActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>

The below code results in a timeout.

It works fine on non-Android Java. What's the matter?

 //@Override
public static void run()
{
    //System.out.println ( "Local Machine IP : "+addrStr.toString (  )  ) ;
    HelloWorldActivity.tv.setText("Trace 1");

    try
    {
        // Retrieve the ServerName
        InetAddress serverAddr; //= InetAddress.getByName(Server.SERVERIP);
        InetAddress ias[] = InetAddress.getAllByName(Server.SERVERNAME);
        serverAddr  = ias[0];

        Log.d("UDP", "C: Connecting...");
        /* Create new UDP-Socket */
        DatagramSocket socket = new DatagramSocket();

        /* Prepare some data to be sent. */
        String strQuery="ÿÿÿÿgetservers"+" "+Server.iProtocol+" "+"'all'";
        Log.d("UDP", strQuery);
        //byte[] buf = ("ÿÿÿÿgetservers 68 'all'").getBytes();
        byte[] buf = strQuery.getBytes();

        /* Create UDP-packet with
         * data & destination(url+port) */
        DatagramPacket packet = new DatagramPacket(buf, buf.length,
                                                   serverAddr, Server.SERVERPORT);

        Log.d("UDP", "C: Sending: '" + new String(buf) + "'");

        /* Send out the packet */
        socket.setSoTimeout(5000);
        socket.send(packet);
        Log.d("UDP", "C: Sent.");
        Log.d("UDP", "C: Done.");

        // http://code.google.com/p/android/issues/detail?id=2917

        byte[] buffer= new byte[1024*100];
        DatagramPacket receivePacket
          = new DatagramPacket(buffer,
                               buffer.length); //, serverAddr, Server.SERVERPORT);
        socket.receive(receivePacket);
        HelloWorldActivity.tv.setText("TTT");

        String x = new String(receivePacket.getData());
        Log.d("UDP", "C: Received: '" + x  + "'");
        HelloWorldActivity.tv.setText(x);

   } catch (Exception e) {
       HelloWorldActivity.tv.setText(e.getMessage());
       Log.e("UDP", "C: Error", e);
   }
}


public class Server
{
    /*
    //public static java.lang.string SERVERIP;
    public static String SERVERNAME = "monster.idsoftware.com";
    public static String SERVERIP = "192.246.40.56";
    public static int SERVERPORT = 27950;
    public static int PROTOCOL = 68;
      */

    //public static String SERVERNAME="monster.idsoftware.com";
    public static String SERVERNAME="dpmaster.deathmask.net";

    public static String SERVERIP="192.246.40.56";
    public static int SERVERPORT=27950;
    //public static int iProtocol= 68; // Quake3
    public static int iProtocol=71; // OpenArena

}

Android manifest:

<?xml version="1.0" encoding="utf-8"?>

<use-permission id="android.permission.READ_CONTACTS" />

    <use-permission android:name="android.permission.WRITE_SETTINGS" />
    <uses-permission android:name="android.permission.READ_CONTACTS" />
    <uses-permission android:name="android.permission.CALL_PHONE" />
    <uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_GPS" />
    <uses-permission android:name="android.permission.ACCESS_MOCK_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
    <uses-permission android:name="android.permission.INTERNET" />
    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
    <uses-permission android:name="android.permission.ACCESS_LOCATION" />
    <uses-permission android:name="android.permission.ACCESS_ASSISTED_GPS" />
    <uses-permission android:name="android.permission.ACCESS_CELL_ID" />

    <uses-permission android:name="android.permission.RECEIVE_SMS" />
    <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.WAKE_LOCK" />

<application
        android:icon="@drawable/icon"
        android:label="AAA New Application"
        >
    <activity android:name="HelloWorldActivity">
        <intent-filter>
            <action android:name="android.intent.action.MAIN"/>
            <category android:name="android.intent.category.LAUNCHER"/>
        </intent-filter>
    </activity>
</application>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

说好的呢 2024-08-25 03:49:16

您是在模拟器上还是在实际手机上进行测试?如果您使用模拟器,则需要了解模拟器上的网络工作原理。最具体的是:

模拟器的每个实例都在虚拟路由器/防火墙服务后面运行,该服务将其与开发计算机的网络接口和设置以及互联网隔离。模拟设备无法看到您的开发计算机或网络上的其他模拟器实例。相反,它只看到它通过以太网连接到路由器/防火墙。

您可能需要设置端口转发,使用模拟器控制台使用adb 命令

Are you testing this on the emulator or on an actual phone? If you're using an emulator you need to be aware of how networking on the emulator works. Most specifically:

Each instance of the emulator runs behind a virtual router/firewall service that isolates it from your development machine's network interfaces and settings and from the internet. An emulated device can not see your development machine or other emulator instances on the network. Instead, it sees only that it is connected through Ethernet to a router/firewall.

You'll probably need to set up port forwarding, either using the Emulator console or using the adb command.

千寻… 2024-08-25 03:49:16

UDP 工作正常。我认为您的服务器没有发送响应,因为您的传出数据包不包含您认为它包含的字节。

请参阅我在您提出的 android bug 中的评论 (http://code. google.com/p/android/issues/detail?id=6163)。

UDP works fine. i don't think your server is sending a response because your outgoing packet doesn't contain the bytes you think it contains.

see my comments in the android bug you raised (http://code.google.com/p/android/issues/detail?id=6163).

凯凯我们等你回来 2024-08-25 03:49:16

要使用 socket.send() 发送/广播 UDP,您需要 android 权限:

<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

但是,即使如此,socket.receive() 似乎也无法捕获广播,即使在相同的上下文中运行时也是如此。我想知道 socket.receive() 是否还有其他权限?...

To send/broadcast UDP using socket.send(), you need the android permission:

<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

However, even so, socket.receive() doesn't seem to catch the broadcast, even when run in the same context. I wonder if there's another permission for socket.receive()?...

战皆罪 2024-08-25 03:49:16
byte[] buf = new byte[256];
socket = new DatagramSocket(port);
DatagramPacket packet = new DatagramPacket(buf, buf.length);
socket.receive(packet);

上面对我有用......你的缓冲区看起来很大?


可能有点牵强,但你想从什么那里得到什么?

如果您尝试与具有两个网卡(一个可以是有线,另一个可以是无线,任意混合)的 XP 计算机进行通信,并且您正在使用 XP 内置防火墙?

然后,仅在计算机上的第一个网络上侦听 UDP 请求,禁用系统上的其他网卡,仅启用您尝试与 Android 设备通信的网卡。

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

Above worked for me... Your buffer seems large?


Might be a little far fetched but what are you trying to receive from?

If you are trying to communicate with a XP machine that has two network cards (one could be wired and the other wireless, any mix) and you are are using XP built in firewall?

Then UDP requests are only listened for on the first network on the computer, disable other network cards on your system, only have enabled the one that your trying to talk your Android device to.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文