2010-01-20 12 views
5

Il codice seguente genera un timeout.Android non riceve mai il pacchetto UDP

Funziona bene su Java non Android. Che cosa c'é?

//@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 

} 

manifest 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

Sei sicuro che il tuo operatore di rete cellulare consenta il traffico UDP in entrata senza restrizioni? – jarnbjo

+0

Non sarebbe in grado di riprodurre Quake3 su Android (tramite USB) nel treno se non fosse così. –

risposta

7

Stai prove sull'emulatore o su un telefono vero e proprio? Se stai usando un emulatore devi essere a conoscenza di how networking on the emulator works. La maggior parte in particolare:

Ogni istanza dell'emulatore corre dietro un servizio/firewall virtuale router che lo isola dalle interfacce e le impostazioni di rete del computer di sviluppo e da internet. Un dispositivo emulato non può vedere la tua macchina di sviluppo o altre istanze di emulazione sulla rete. Invece, vede solo che è connesso tramite Ethernet a un router/firewall.

Avrete probabilmente bisogno di configurare il port forwarding, sia using the Emulator console o using the adb command.

+0

non funziona anche sul dispositivo attuale ... ha sempre timeout, sia nell'emulatore che nel dispositivo reale. Funziona perfettamente con la macchina di sviluppo in un normale ambiente java. E posso accedere ad internet su Android ... –

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

Sopra ha funzionato per me ... Il tuo buffer sembra grande?


Potrebbe essere un po 'inverosimile ma cosa stai cercando di ricevere da?

Se si sta tentando di comunicare con una macchina XP che ha due schede di rete (una potrebbe essere cablata e l'altra wireless, qualsiasi mix) e si sta utilizzando il firewall integrato XP?

Quindi le richieste UDP vengono ascoltate solo sulla prima rete del computer, disabilitare altre schede di rete sul sistema, solo quelle che si tenta di comunicare con il proprio dispositivo Android.

+0

grande? 1024 * 100 = 100 kb. Non è molto Ho anche provato su Android direttamente, non sull'emulatore, ma lo stesso risultato lì. Proverò con 256 byte, comunque. –

+0

Osservando il commento di jarnbjo, il codice di esempio sopra ha funzionato con il mio dispositivo collegato via WiFi non tramite la rete cellulare. – optics

+0

Ci proverò quando torno a casa e avrò wifi –

2

UDP funziona correttamente. non penso che il tuo server stia inviando una risposta perché il tuo pacchetto in uscita non contiene i byte che pensi che contenga.

vedere i miei commenti nel bug Android che hai sollevato (http://code.google.com/p/android/issues/detail?id=6163).

+0

cosa succede se viene ricevuto ma durante l'afflusso costante di pacchetti alcuni vengono persi. Qualche idea per risolvere quel problema –

0

Per inviare/trasmettere UDP utilizzando socket.send(), è necessario il permesso di Android:

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

Tuttavia, anche così, socket.receive() non sembra cogliere la trasmissione, anche quando correre nello stesso contesto. Mi chiedo se c'è un altro permesso per socket.receive()? ...

Problemi correlati