2017-05-16 38 views
1

UDPプロトコルを使用して電話機を接続できる物理デバイスがあります。 これは問題です:デバイスをプログラミングしたエレクトロニクスエンジニアは、このデバイスと(UDPも使用して)相互作用するデスクトッププログラムを作成し、すべてがスムーズに実行されます:デバイスはコマンドを受け取り、問題や例外なしに応答を送信します。Android 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; 

}

私が受け取るtimeoutexceptionです:

 


> 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)* 

+0

多分あなたはスレッドで受信を開始し、何らかの理由で送信されたデータが到着しなかった場合、デバイスは応答を送信しないかもしれません – lelloman

+0

どのポート番号を使用しますか?ポートでリッスンできる<1024 –

+0

ipAddress - 192.168.1.1、 ポート - 8010 –

答えて

0

は、私は、パケットが送信される前にタイムアウトがで蹴ることだけを推測することができます。これは、送信しようとしているパケットが大きすぎることを意味します。

あなたが言うとき:答えが来たら、もう一つは来ません。それは私には分かりません。私の推測では、1つのパケットを受信したが、もう1つは受信していないということです。 クイックテストは、タイムアウトを増やすことです。これは、受信するパケットが大きすぎることを確認します。 小さなパケットを送信することをお勧めします。あなたのアンドロイドアプリに問題を探すためにいくつかのデバッグポイントを挿入しましたか?

+0

BUFFER_SIZEは常に38バイトです。変更されることはありません。 38バイトの配列 - デバイスが送受信できる固定データサイズです。 –

+0

タイムアウトの遅延を長くしようとしましたか? –

関連する問題