Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/178.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/fsharp/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java-android UDP不可靠性_Java_Android_Udp_Packet_Loss - Fatal编程技术网

java-android UDP不可靠性

java-android UDP不可靠性,java,android,udp,packet,loss,Java,Android,Udp,Packet,Loss,我在Android上遇到了严重的UDP数据包丢失,这毫无意义。情况如下: 运行java客户端的PC连接到家庭网络 运行连接到家庭网络的java服务器(android)的手机 家庭路由器是全新的WRT1900ac。网络具有internet连接 UDP数据包很小(

我在Android上遇到了严重的UDP数据包丢失,这毫无意义。情况如下:

  • 运行java客户端的PC连接到家庭网络
  • 运行连接到家庭网络的java服务器(android)的手机
  • 家庭路由器是全新的WRT1900ac。网络具有internet连接
  • UDP数据包很小(<15字节)
  • 症状

  • 若PC向另一台PC发送UDP数据包(两台都在同一个网络上),它工作得很好(几乎并没有数据包丢失)

  • 如果Android在同一个网络上向PC发送UDP数据包,它也能很好地工作(几乎没有数据包丢失)

  • 如果PC在同一个网络上向Android发送UDP,我会收到极端的数据包丢失(50%或更多的时间,但情况有所不同)

  • 大多数时候,我被迫发送10次这样的数据包才能通过。其他时间都会有相当长的延迟。非常奇怪的行为只发生在android的接收端。如果我用在java上运行相同代码的pc替换android,或者只是通过数据包发送者的UDP服务器接收数据包,我就不会有丢失问题。我注意到的另一件事是,如果不是通过路由器,而是通过另一个没有互联网连接或没有其他客户端的接入点,性能似乎会显著提高。这是意料之中的,但我的问题是,为什么Android的接收端会出现如此糟糕的性能,并丢失如此多的数据包。当安卓被另一台运行相同代码、在同一网络上的电脑取代时,就没有问题了
    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();
        }
    }
    
    android上的UDP接收代码位于UDP服务器类中:

    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()”方法实例化:


    我在一些安卓设备通过WiFi向TFTP(基于UDP)服务器发送文件时遇到了灾难性的后果,但它似乎与其他安卓设备配合得很好

    数据块(从设备到服务器)已正确发送,但ack块(从服务器到设备)似乎丢失了

    事实证明,我必须为那些有故障的设备获得一个多播锁才能正常工作(归功于)


    希望这有帮助。

    不确定这是否可以通过这种方式解决。。。如果你必须使用诸如wireshark之类的工具来仔细观察所有网络流量以了解发生了什么,我也不会感到惊讶。如上所述,试着使用wireshark看看发生了什么。另外,如果可能的话,尝试另一个android设备,看看你的设备是否有问题。
        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();
        }
    
    WifiManager wifi = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
    WifiManager.MulticastLock multicastLock = wifi.createMulticastLock("multicastLock");
    multicastLock.setReferenceCounted(true);
    multicastLock.acquire();
    
    ...
    
    multicastLock.release();