2010-01-20 137 views
5

以下代码会导致超时。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> 

+0

您确定您的手机网络运营商允许无限制的入站UDP流量吗? – jarnbjo 2010-01-20 14:36:32

+0

如果不是这样,将无法在火车上通过android(通过usb)播放Quake3。 – 2010-01-20 15:50:54

回答

7

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

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

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

+0

它在实际设备上也失败了... 它总是超时,在模拟器以及实际设备中。它在正常的java环境中可以在开发机器上正常工作。我可以访问互联网上的Android ... – 2010-01-20 13:54:20

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

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


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

如果您试图与具有两个网卡(一个可能是有线和另一个无线,任何混合)的XP机器通信,并且您正在使用内置防火墙的XP?

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

+0

大吗? 1024 * 100 = 100 kb。这并不多。 我也试过在android上直接,而不是模拟器,但在那里的结果相同。不过,我会尝试256字节。 – 2010-01-20 14:36:26

+0

注意到jarnbjo的评论上面的示例代码与通过WiFi连接的设备一起使用,而不是通过单元网络。 – optics 2010-01-20 14:50:39

+0

我会尝试,当我回到家里,并有WiFi – 2010-01-20 15:52:17

2

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

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

+0

如果它的接收,但在持续的数据包流入过程中有些错过了。任何想法来解决这个问题 – 2016-08-11 12:49:38

0

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

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

然而,即便如此,socket.receive()似乎并没有赶上直播,即使在相同的环境下运行。我想知道是否有socket.receive()的另一个权限?...