Android从不接收UDP数据包

时间:2010-01-20 12:23:33

标签: java android udp

以下代码会导致超时。

它适用于非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

}

Android清单:

<?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>

4 个答案:

答案 0 :(得分:7)

您是在模拟器上还是在实际手机上进行测试?如果您使用的是模拟器,则需要注意how networking on the emulator works。最具体的是:

  

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

您可能需要设置端口转发,using the Emulator consoleusing the adb command

答案 1 :(得分:2)

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

在你提出的android bug(http://code.google.com/p/android/issues/detail?id=6163)中查看我的评论。

答案 2 :(得分:1)

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

以上为我工作......你的缓冲区似乎很大?


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

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

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

答案 3 :(得分:0)

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

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

然而,即便如此,即使在相同的上下文中运行,socket.receive()似乎也不会捕获广播。我想知道socket.receive()是否有另一个权限?...