2012-01-27 9 views
1

基本的なSSDPコマンドを処理するUDPレスポンダを開発しています。このコードの目的は自動検出を行うことで、サーバーが特定のグループにマルチキャストを送信するときに、他のすべての加入デバイスは、マルチキャストを送信したホストとポートにその存在を知らせるUDPパケットを送り返す必要があります。私のAndroidデバイスはパケットを受信して​​送信しますが、getSocketAddress()メソッドからSocketAddressオブジェクトを取得するには時間がかかりすぎるため、サーバーがタイムアウトしてリスニングポートを閉じ、アンドロイドデバイスからパケットを戻しません。getSocketAddress()メソッドは、遅延を引き起こし、Androidの通信遅延につながります。

ここに私のコードです:

public void onCreate(Bundle savedInstanceState) { 
    super.onCreate(savedInstanceState); 
    setContentView(R.layout.main); 

    MulticastSocket ms = null; 
    byte[] packBuf = new byte[128]; 
    try { 
     ms = new MulticastSocket(32410); 
     ms.joinGroup(InetAddress.getByName("239.255.255.250")); 
    } catch (IOException e3) { 
     // TODO Auto-generated catch block 
     e3.printStackTrace(); 
    } 

    while (true) 
    { 
     DatagramPacket receivedPack = new DatagramPacket(packBuf, packBuf.length); 
     try { 
      ms.receive(receivedPack); 
      Log.d(TAG, "Received data"); 

     } catch (IOException e3) { 
      // TODO Auto-generated catch block 
      e3.printStackTrace(); 
     } 

     String responseStr = "HTTP/1.0 200 OK\n" + 
      "Content-Type: app\n" + 
      "Resource-Identifier: 945e7dd5913ab45f1db4f271a1620b9471fb7d4d\n" + 
      "Name: Test App\n" + 
      "Port: 8888\n" + 
      "Updated-At: 1319511680\n" + 
      "Version: 0.9.3.4-29679ad\n" + 
      "Content-Length: 23\n\n" + 
      "<message>test</message>"; 

     byte[] response = responseStr.getBytes(); 

     DatagramSocket sendSocket = null; 
     try { 
      sendSocket = new DatagramSocket(); 

     } catch (IOException e2) { 
      // TODO Auto-generated catch block 
      Log.e(TAG,"Erro",e2); 
     } 

     DatagramPacket outPack; 
     try { 
      outPack = new DatagramPacket(response, responseStr.length(), receivedPack.getSocketAddress()); 
      sendSocket.send(outPack); 
     } catch (UnknownHostException e1) { 
      Log.e(TAG,"Erro",e1); 
     } 
     catch (IOException e) { 
      Log.e(TAG,"Erro",e); 
     } 
     catch (Exception e) 
     { 
      Log.e(TAG,"Erro",e); 
     } 
    } 
} 

任意のアイデア?事前に

おかげで、

FBR

答えて

0

2のものは、変更するとどうなります)...心に

1を来る:

outPack = new DatagramPacket(response, responseStr.length(), receivedPack.getSocketAddress()); 

outPack = new DatagramPacket(response, responseStr.length(), receivedPack.getAddress(), receivedPack.getPort()); 

2)私はこの種の問題を持つ覚えていますホームオートメーションシステムに組み込まれたJava。私たちの短期的な解決策は、マシンファイルとマルチキャストアドレスのほとんどをhostsファイルに入れることでした。長期的には、我々はローカルのDNSサーバで終わった。

Java Networkスタックのどこかに、メモリにDNS障害をキャッシュする時間を示すパラメータがあります。私たちはその数を10秒ではなく5分に増やしました。

+0

私は提案された変更を行い、それが機能しました。どうもありがとう! – ForeignerBR

1

最も可能性の高い問題はgetSocketAddress()がマルチキャストアドレスであるか、単にいずれかによることにタイムアウトされたIPアドレスのDNS名を解決しようとしていることです一般的なDNSの遅れ。

InetSocketAddressクラスには、この動作を制御できるコンストラクタオプションneedResolvedがあります。残念ながら、DatagramPacket.getSocketAddress()では、その設定をfalseにするように指定することはできません。

これは、ここでのいくつかの最近の議論で、明らかに既知の問題です: Issue 12328: DatagramChannel - cannot receive without a hostname lookup

スレッドが、これはアンドロイド3.0で修正されていることを示唆している、とAndroid 2.0のための回避策のカップルを提供しているかもしれないまたはかもしれませんうまくいかない。あなたのケースでは

、あなたは0にINADDR_ANYへInetSocketAddressセットとneedsResolvedセットでポート0を作成してみてください、そして、あなたはreceivedPackを作成するときにそれを渡すことができます。うまくいけばはそれを再利用し、設定を覚えています。

関連する問題