Android UDP通讯。无法从设备接收数据

时间:2017-05-16 14:13:43

标签: android

有一个物理设备可以使用UDP协议连接手机。 问题在于:编程设备的电子工程师编写了一个与该设备交互的桌面程序(也使用UDP),一切运行顺利:设备接收命令并发送响应,没有任何问题和例外。

但随着手机 - 麻烦...手机通过WiFi连接到设备没有问题,发送命令也没有任何问题(没有时间的感觉),但接收有一个问题 - 一旦答案来了,其他的不来。一般来说,socket.receive不像桌面程序那样稳定工作,经常弹出timeoutexception ...

我提供了所需的所有权限:

<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />

我在AsyncTask中运行一个命令:

private class GetStatus extends AsyncTask<byte[], Void, UdpResult> {

@Override
protected void onPreExecute() {
    super.onPreExecute();
    isPinging = true;

    if (udpSettingsListener != null) {
        udpSettingsListener.onPreGetStatus();
    }
}

@Override
protected UdpResult doInBackground(byte[]... params) {
    UdpResult udpResult = sendCommand(params[0]);
    udpResult.opName = "GetStatus";
    udpResult.odDate = System.currentTimeMillis();
    udpResults.add(udpResult);
    return udpResult;
}

@Override
protected void onPostExecute(UdpResult result) {
    super.onPostExecute(result);
    isPinging = false;

    if (udpSettingsListener != null) {
        if (result.succeed) {
            udpSettingsListener.onGotStatus(new DeviceStatus(result.response));
        } else {
            udpSettingsListener.onFailedToGetStatus(result.exception);
        }
    }
}

}

这是与设备通信的'sendCommand'功能:

private UdpResult sendCommand(byte[] command) {
UdpResult udpResponse = new UdpResult();
try {
    Thread.sleep(sleepFor);
} catch (InterruptedException e) {
    e.printStackTrace();
}
do {
    udpResponse.command = command;
    udpResponse.response = new byte[BUFFER_SIZE];
    DatagramSocket socket = null;

    try {
        socket = new DatagramSocket();
        socket.setSendBufferSize(BUFFER_SIZE);
        socket.setReceiveBufferSize(BUFFER_SIZE);
        socket.setSoTimeout(timeout);
        InetAddress inetAddress = InetAddress.getByName(ipAddress);
        DatagramPacket sendPacket = new DatagramPacket(udpResponse.command, BUFFER_SIZE, inetAddress, port);
        DatagramPacket receivePacket = new DatagramPacket(udpResponse.response, BUFFER_SIZE, inetAddress, port);
        socket.send(sendPacket);
        socket.receive(receivePacket);
        udpResponse.succeed = true;
    } catch (Exception e) {
        Log.e(TAG, "sendCommand: ", e);
        udpResponse.succeed = false;
    } finally {
        if (socket != null) {
            socket.close();
        }
    }
    udpResponse.attempts++;
} while (udpResponse.attempts < maxAttempts && !udpResponse.succeed);
return udpResponse;

}

以下是我收到的时间表:



> java.net.SocketTimeoutException  at
> libcore.io.IoBridge.maybeThrowAfterRecvfrom(IoBridge.java:598)  at
> libcore.io.IoBridge.recvfrom(IoBridge.java:556)  at
> java.net.PlainDatagramSocketImpl.doRecv(PlainDatagramSocketImpl.java:163)
> at
> java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:171)
> at java.net.DatagramSocket.receive(DatagramSocket.java:274)  at
> com.andreyserdyuk.gaash.helpers.UdpHelper.sendCommand(UdpHelper.java:326)
> at
> com.andreyserdyuk.gaash.helpers.UdpHelper.access$1400(UdpHelper.java:27)
> at
> com.andreyserdyuk.gaash.helpers.UdpHelper$SetRtc.doInBackground(UdpHelper.java:371)
> at
> com.andreyserdyuk.gaash.helpers.UdpHelper$SetRtc.doInBackground(UdpHelper.java:357)
> at android.os.AsyncTask$2.call(AsyncTask.java)  at
> java.util.concurrent.FutureTask.run(FutureTask.java:237)  at
> android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java)  at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)
> at java.lang.Thread.run(Thread.java:818)  Caused by:
> android.system.ErrnoException: recvfrom failed: EAGAIN (Try again)  at
> libcore.io.Posix.recvfromBytes(Native Method)  at
> libcore.io.Posix.recvfrom(Posix.java:185)  at
> libcore.io.BlockGuardOs.recvfrom(BlockGuardOs.java:250)  at
> libcore.io.IoBridge.recvfrom(IoBridge.java:553)  at
> java.net.PlainDatagramSocketImpl.doRecv(PlainDatagramSocketImpl.java:163)*
> at
> java.net.PlainDatagramSocketImpl.receive(PlainDatagramSocketImpl.java:171)*
> at java.net.DatagramSocket.receive(DatagramSocket.java:274)*  at
> com.andreyserdyuk.gaash.helpers.UdpHelper.sendCommand(UdpHelper.java:326)*
> at
> com.andreyserdyuk.gaash.helpers.UdpHelper.access$1400(UdpHelper.java:27)*
> at
> com.andreyserdyuk.gaash.helpers.UdpHelper$SetRtc.doInBackground(UdpHelper.java:371)*
> at
> com.andreyserdyuk.gaash.helpers.UdpHelper$SetRtc.doInBackground(UdpHelper.java:357)*
> at android.os.AsyncTask$2.call(AsyncTask.java)*  at
> java.util.concurrent.FutureTask.run(FutureTask.java:237)*  at
> android.os.AsyncTask$SerialExecutor$1.run(AsyncTask.java)*  at
> java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1112)*
> at
> java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:587)*
> at java.lang.Thread.run(Thread.java:818)*

1 个答案:

答案 0 :(得分:0)

我只能猜测你的超时会在数据包发送之前启动。这意味着您尝试发送的数据包太大。

当你说:一旦答案到来,另一个不会来。我不清楚。我的猜测是你收到一个数据包,但没有收到另一个数据包。 一个快速测试是增加超时。这将确认要接收的数据包太大。 我的建议是尝试发送较小的数据包。在Android应用程序中插入一些调试点来查找问题?