Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/android/180.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_Sockets_Networking_Udp - Fatal编程技术网

Java 某些Android设备上严重的UDP数据包丢失

Java 某些Android设备上严重的UDP数据包丢失,java,android,sockets,networking,udp,Java,Android,Sockets,Networking,Udp,我浏览了互联网,没有结果。我们面临着一个问题,一些安卓设备经历了严重的数据包丢失。为了提供一些背景信息,应用程序连接到特定的Wifi,并查找端口17216上广播的UDP数据包。这些数据包的大小为832字节,不包括包装的头,并以每秒4个的常规速率发送 我们只在两台设备上遇到了这个问题,一台低端的Turbox Rubik II平板电脑和一台华硕的HD7记事本。我们测试过的其他设备(手机和平板电脑)都在规定的固定时间间隔收集数据包 接收数据包的功能如下: public void run() {

我浏览了互联网,没有结果。我们面临着一个问题,一些安卓设备经历了严重的数据包丢失。为了提供一些背景信息,应用程序连接到特定的Wifi,并查找端口17216上广播的UDP数据包。这些数据包的大小为832字节,不包括包装的头,并以每秒4个的常规速率发送

我们只在两台设备上遇到了这个问题,一台低端的Turbox Rubik II平板电脑和一台华硕的HD7记事本。我们测试过的其他设备(手机和平板电脑)都在规定的固定时间间隔收集数据包

接收数据包的功能如下:

public void run()
{
    while (isUDPServerRunning)
    {
        try
        {
            socket.receive(packet);

            ProcessRawPacketData();

            DisplayLoggingInfo();

        }
        catch (IOException e)
        {
            Log.e("receive", e.getMessage());
            e.printStackTrace();
        }
    }
}
这是
Runnable
的一部分。套接字是这样创建的:

byte[] buffer = new byte[1024];

DatagramSocket socket;
DatagramPacket packet = new DatagramPacket(buffer, buffer.length);
在我们的
服务
扩展的
onCreate()方法中初始化套接字时:

socket = new DatagramSocket(SERVERPORT);
无线模块正在接收数据包。我们已经确认,通过在其中一个设备上加根并安装数据包嗅探器,问题一定与代码有关

在受影响的设备上,数据包在几秒钟内被正确接收,然后出现持续几秒钟的完全丢失,因此我估计丢失率将超过50%

任何帮助都将不胜感激。我们正在拔头发

更新关于数据包嗅探器,我错了。数据包嗅探器似乎也在丢失根设备上的几个相关数据包。不过,有时候,只要启动数据包嗅探器就可以解决问题!像下面建议的那样打开/关闭蓝牙似乎没有什么区别。这可能是另一个硬件问题吗

更新2下面是一个在
socket.receive()
行之后立即打印的日志示例。注意它是如何跳过半分钟的数据包,然后在几秒钟内正常工作的

05-25 15:44:38.670: D/LOG(4393): Packet Received
05-25 15:44:38.941: D/LOG(4393): Packet Received
05-25 15:45:09.482: D/LOG(4393): Packet Received
05-25 15:45:09.716: D/LOG(4393): Packet Received
05-25 15:45:09.928: D/LOG(4393): Packet Received
05-25 15:45:10.184: D/LOG(4393): Packet Received
05-25 15:45:10.451: D/LOG(4393): Packet Received
05-25 15:45:10.661: D/LOG(4393): Packet Received

这听起来非常类似于Android(和iOS——事实上,任何结合了WiFi和蓝牙的设备)设备上出现的蓝牙干扰症状

2.4Ghz WiFi和蓝牙共享相同的带宽,并且可能相互干扰-在某些设备上,这是非常明显的,可能是由于内部布局

您也可能在某些设备上看到它,而在其他设备上看不到它,因为它们支持的WiFi版本-较新的5GHz WiFi不会以相同的方式干扰蓝牙,但一些较旧或更基本的Android设备可能不支持此功能


您可以通过在测试时关闭设备上的蓝牙功能(如果您的应用程序可以在没有蓝牙的情况下运行)来轻松测试这是否是原因。

只是一个粗略的猜测,但是您对数据包的计算需要多长时间?是否有可能为套接字分配的缓冲区已满并开始丢弃包

我知道,对于大约4KB/s的传输速率来说,这听起来不太可能。。。但是如果你的计算时间超过250毫秒,这迟早会发生。这也解释了为什么有些设备工作起来像个符咒,而另一些设备却没有


您是否已尝试删除计算并仅打印“package received”消息以进行调试?

有趣的是,正在经历UDP数据包丢失的两个设备碰巧都有Mediatek SOC。您的其他测试设备是否有相同的芯片组

这可能是这些SOC的Wi-Fi驱动程序中的错误。由于它仅在UDP中显示,并且并非总是100%,因此到目前为止,每个人都可能没有注意到它。

数据包丢失(当然,您知道)可能会在传输过程中的多个阶段发生:

  • 从服务器发送
  • 网络传输
  • 客户的物理接收和硬件处理
  • 在内核/OS中处理/缓冲数据包
  • 处理/缓冲应用程序中的数据包
  • 通过让其他设备在连接到同一Wifi路由器时收听同一广播,您可以快速检查点1或点2是否存在问题。听起来你已经这么做了,没有问题。(请注意,如果在服务器上运行WireShark转储,则在步骤2(有时甚至是步骤1)中丢弃的数据包可能不会丢失。)

    因此,第3点到第5点可能是问题所在,并且可能更难区分

    以下几点可能会有所帮助:

    • 就像@Mick建议的那样,不要只是在收到数据包时打印出来,而是给每个数据包增加一个ID号,以确定你是否真的丢失了一个数据包,或者它是否只是被延迟了
    • 将数据包接收代码移动到它自己的线程(如果还没有)和该线程中,以最大限度地减少代码占用午餐线路的可能性。考虑到记事本是一台四核1.2GHz的机器,甚至不需要最高优先级,但是如果您当前没有在自己的专用线程中运行接收循环,您可能会看到hick ups。如果这解决了问题,只需使用一个最小的接收循环将数据包粘贴到您自己的缓冲队列中,并由一个独立的线程处理它们
    • 检查/增加数据包缓冲区的大小,以便通过()接收数据包。请确保指定可以容纳多个数据包的大小。考虑到运行数据包嗅探器有时似乎有帮助,听起来确实有一些套接字设置可以改善情况,嗅探器恰好设置了这些设置
    • 在服务器上您还可以向数据包添加标签,告知所有相关设备如何处理数据包。如果你打电话,你会要求所有相关人员优化他们的数据包处理,以获得最大的可靠性。并非所有设备都会在意,但这可能会有所不同
    • 您可以尝试使用而不是DatagramSockets,然后使用等待下一个数据包读取。虽然这在技术上不应该有什么不同,但有时使用不同的