2012-01-27 188 views
1

我正在開發一個UDP響應程序來處理基本的SSDP命令。這段代碼的目的是做自動發現,所以當服務器發送一個多播到一個特定的組時,所有其他訂閱的設備應該發回一個UDP數據包,通知它的存在到發送多播的主機和端口。我的android設備收到併發送數據包就好了,但由於getSocketAddress()方法返回SocketAddress對象太長,服務器超時,關閉偵聽端口,並且永遠不會從android設備獲取數據包。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

兩件事情浮現在腦海中......當你改變

1)會發生什麼:

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

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

2)我記得有這種問題有在家庭自動化系統上嵌入Java。我們的短期解決方案是將大部分機器和多播地址放入主機文件中。長期來看,我們最終使用了本地DNS服務器。

Java網絡堆棧中有一個參數,告訴它在內存中緩存DNS故障需要多長時間。我認爲這個數字是5分鐘而不是10秒。

+0

我做了建議的更改,它工作。非常感謝! – ForeignerBR 2012-02-02 02:02:09

1

最可能的問題是getSocketAddress()試圖將IP地址解析的DNS名稱,這是超時或者是由於它是一個組播地址或者只是一般DNS滯後。

InetSocketAddress類有一個構造函數選項needResolved它可以控制這種行爲。不幸的是,DatagramPacket.getSocketAddress()不允許你指定你想要設置爲false。

這顯然是一個已知的問題,在這裏它的一些最近的討論: Issue 12328: DatagramChannel - cannot receive without a hostname lookup

線程表明,這已得到修復的Android 3.0,並提供了一些解決方法爲Android 2.0可能會或可能不行。

在你的情況,你可以嘗試創建一個InetSocketAddress設置爲INADDR_ANY和端口0與needsResolved設置爲0,然後再傳遞,當你創建receivedPack英寸希望將重用並記住該設置。