getSocketAddress()方法会导致延迟,从而导致Android中的通信延迟
我正在开发一个UDP响应程序来处理基本的SSDP命令。这段代码的目的是进行自动发现,因此,当服务器向特定组发送多播时,所有其他订阅的设备都应该向发送多播的主机和端口发回一个UDP数据包,宣布其存在。我的android设备接收和发送数据包都很正常,但由于从getSocketAddress()方法返回SocketAddress对象所需的时间太长,服务器超时,关闭侦听端口,并且从未从android设备返回数据包 这是我的密码:getSocketAddress()方法会导致延迟,从而导致Android中的通信延迟,android,udp,Android,Udp,我正在开发一个UDP响应程序来处理基本的SSDP命令。这段代码的目的是进行自动发现,因此,当服务器向特定组发送多播时,所有其他订阅的设备都应该向发送多播的主机和端口发回一个UDP数据包,宣布其存在。我的android设备接收和发送数据包都很正常,但由于从getSocketAddress()方法返回SocketAddress对象所需的时间太长,服务器超时,关闭侦听端口,并且从未从android设备返回数据包 这是我的密码: public void onCreate(Bundle saved
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);
}
}
}
public void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
多播套接字ms=null;
字节[]packBuf=新字节[128];
试一试{
ms=新的多播套接字(32410);
ms.joinGroup(InetAddress.getByName(“239.255.255.250”);
}捕获(IOE3异常){
//TODO自动生成的捕捉块
e3.printStackTrace();
}
while(true)
{
DatagramPacket receivedPack=新的DatagramPacket(packBuf,packBuf.length);
试一试{
ms.receive(receivedPack);
Log.d(标签“接收数据”);
}捕获(IOE3异常){
//TODO自动生成的捕捉块
e3.printStackTrace();
}
String responsest=“HTTP/1.0 200正常\n”+
“内容类型:应用程序\n”+
“资源标识符:945e7dd5913ab45f1db4f271a1620b9471fb7d4d\n”+
“名称:测试应用程序\n”+
“端口:8888\n”+
“更新地址:1319511680\n”+
“版本:0.9.3.4-29679ad\n”+
“内容长度:23\n\n”+
“测试”;
byte[]response=responsest.getBytes();
DatagramSocket sendSocket=null;
试一试{
sendSocket=newdatagramsocket();
}捕获(IOE2异常){
//TODO自动生成的捕捉块
日志e(标签“Erro”,e2);
}
数据包输出;
试一试{
outPack=newdatagrampacket(response,responseStr.length(),receivedPack.getSocketAddress());
sendSocket.send(outPack);
}捕获(未知后异常e1){
日志e(标签“Erro”,e1);
}
捕获(IOE异常){
Log.e(标签“Erro”,e);
}
捕获(例外e)
{
Log.e(标签“Erro”,e);
}
}
}
有什么想法吗
提前感谢,
fbr最有可能的问题是
getSocketAddress()
正在尝试解析IP地址的DNS名称,由于它是多播地址或只是一般DNS延迟,该名称正在超时
InetSocketAddress
类有一个构造函数选项needResolved
,可以控制此行为。不幸的是,DatagramPacket.getSocketAddress()
似乎不允许您指定要将其设置为false
这显然是一个已知的问题,最近在这里进行了一些讨论:
该线程表明,Android 3.0中已经解决了这一问题,并为Android 2.0提供了一些变通方法,这些方法可能有效,也可能无效
在您的情况下,您可以尝试创建一个
InetSocketAddress
设置为INADDR\u ANY,并将需要解决的端口0设置为0,然后在创建receivedPack
时将其传入。希望receive()
能够重新使用它并记住设置。最可能的问题是getSocketAddress()
正在尝试解析IP地址的DNS名称,这可能是由于它是多播地址或只是一般DNS延迟而超时
InetSocketAddress
类有一个构造函数选项needResolved
,可以控制此行为。不幸的是,DatagramPacket.getSocketAddress()
似乎不允许您指定要将其设置为false
这显然是一个已知的问题,最近在这里进行了一些讨论:
该线程表明,Android 3.0中已经解决了这一问题,并为Android 2.0提供了一些变通方法,这些方法可能有效,也可能无效
在您的情况下,您可以尝试创建一个InetSocketAddress
设置为INADDR\u ANY,并将需要解决的端口0设置为0,然后在创建receivedPack
时将其传入。希望receive()
能够重用它并记住设置。2件事浮现在脑海中
1) 当你改变时会发生什么:
outPack = new DatagramPacket(response, responseStr.length(), receivedPack.getSocketAddress());
到
2) 我记得在家庭自动化系统中使用嵌入式Java时遇到过这种问题。我们的短期解决方案是将大多数机器和多播地址放在主机文件中。长期以来,我们最终得到了一个本地DNS服务器
Java网络堆栈中有一个参数,告诉它在内存中缓存DNS故障的时间。我想,我们把这个数字提高到了5分钟,而不是10秒。我想到了两件事
1) 当你改变时会发生什么:
outPack = new DatagramPacket(response, responseStr.length(), receivedPack.getSocketAddress());
到
2) 我记得在家庭自动化系统中使用嵌入式Java时遇到过这种问题。我们的短期解决方案是将大多数机器和多播地址放在主机文件中。长期以来,我们最终得到了一个本地DNS服务器
Java网络堆栈中有一个参数,告诉它在内存中缓存DNS故障的时间。我想,我们把这个数字提高到了5分钟,而不是10秒