2010-01-20 140 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()的另一個權限?...