2016-12-19 22 views
4

我有极端UDP数据包丢失与Android,它没有任何意义。这种情况如下:连接到连接到家庭网络 java - android UDP不可靠

  • 家庭路由器的家庭网络
  • 电话运行Java服务器(机器人)是一个全新的WRT1900ac

    1. PC上运行Java客户端。网络具有互联网连接。
    2. UDP数据包很小(< 15字节)

    症状

    1. 如果PC机发送UDP数据包到另一台电脑(包括同一网络上),它的工作原理很好(几乎没有丢包)。

    2. 如果Android向同一网络上的PC发送UDP数据包,它也工作得很好(几乎没有丢包)。

    3. 如果PC在同一网络上向Android发送UDP,则会导致极大的数据包丢失(50%或更多 - 但不尽相同)。

    大多数时候,我不得不送样10次的数据包来获得一个通过。其他时间都经历了相当长的一段时间。非常奇怪的行为,只发生在android的接收端。如果我取代 Android与PC上运行相同的代码在Java上或只是通过Packet Sender的UDP服务器接收数据包我没有损失问题。我注意到的另一件事是,如果不通过路由器,我会通过另一个没有互联网连接的接入点,或者没有其他客户端的性能显着提高。这是预期的,但我的问题是,为什么Android的接收端看到这样的性能差并丢失这么多的数据包。当Android被替换为运行相同代码的另一台PC并且在同一网络上时,没有问题。 Android没有问题发送数据包(没有数据包丢失)。因此它必须在接收端与其他Android相关...

    我也尝试用分组发送器替换PC代码,并且得到相同的结果。这个问题似乎是Android的接收端。我在PC端和android上运行相同的UDP代码。

    的UDP发送代码很简单:

    public void sendMessage(String message) 
    { 
        try { 
         DatagramSocket ds = new DatagramSocket(); 
         DatagramPacket dp; 
         InetAddress local = InetAddress.getByName(ipPool); 
         dp = new DatagramPacket(message.getBytes(), message.length(), local, port); 
         ds.setBroadcast(true); 
         ds.send(dp); 
         ds.close(); 
        } catch (Exception e) { 
         e.printStackTrace(); 
        } 
    } 
    

    的UDP接收在UDP服务器类上的Android生命代码:

    public class UDP_Server 
    { 
        CommandParser commandParser; 
    
        public UDP_Server(MainActivity mainActivity) 
        { 
         Log.i("Udp tutorial", "---------------------------Starting UDP SERVER"); 
    
         commandParser = new CommandParser(mainActivity); 
         String text; 
         int server_port = 9876; 
         try 
         { 
          DatagramSocket s = new DatagramSocket(server_port); 
          s.setBroadcast(true); 
          //s.setReceiveBufferSize(163840); 
    
    
          while (true) 
          { 
           byte[] message = new byte[1024]; 
           DatagramPacket p = new DatagramPacket(message, message.length); 
    
           s.receive(p); 
           text = new String(message, 0, p.getLength()); 
           Log.d("Udp tutorial","message:" + text); 
           //commandParser.parseCommand(text); 
           //s.close(); 
          } 
         } catch (SocketException e) 
         { 
          e.printStackTrace(); 
         } catch (IOException e) { 
          e.printStackTrace(); 
         } 
    
        } 
    } 
    

    的UDPServer。java类是通过主要活动实例“的onCreate()”方法:

    protected void onCreate(Bundle savedInstanceState) { 
         super.onCreate(savedInstanceState); 
         setContentView(R.layout.activity_main); 
    
         StrictMode.ThreadPolicy policy = new StrictMode.ThreadPolicy.Builder().permitAll().build(); 
         StrictMode.setThreadPolicy(policy); 
    
         wm = (WifiManager) getSystemService(WIFI_SERVICE); 
    
         Log.i("Udp tutorial", "---------------------------HERE 1"); 
         Thread thread = new Thread(new Runnable() 
         { 
          public void run() 
          { 
           UDP_Server svr = new UDP_Server(MainActivity.this); 
          } 
         }); 
    
         thread.setPriority(Thread.MAX_PRIORITY); 
         thread.start(); 
    //  TCPServer server = new TCPServer(); 
        } 
    
  • +0

    不知道这是否可以通过这种方式解决......如果您不得不使用wireshark等工具仔细观察所有网络流量来确定发生了什么,它不会让我感到意外。 – GhostCat

    +0

    如上所述,尝试使用wireshark,看看发生了什么。另外,如果可能的话尝试其他Android设备,看看您的设备是否有问题。 – jython234

    回答

    0

    我曾与一些Android设备通过WiFi发送文件到TFTP(基于UDP)服务器,但它似乎工作带来灾难性的后果以及其他Android设备。

    数据块(从设备到服务器)被正确发送,但是ack块(从服务器到设备)似乎失去了缓冲区。

    原来我不得不获取组播锁定为那些有故障的设备正常工作(学分https://www.b4x.com/android/forum/threads/enable-multicast.43321/#post-263242

    WifiManager wifi = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE); 
    WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock"); 
    multicastLock.setReferenceCounted(true); 
    multicastLock.acquire(); 
    
    ... 
    
    multicastLock.release(); 
    

    希望这有助于。