2012-01-27 180 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英寸希望将重用并记住该设置。