getSocketAddress()方法会导致延迟,从而导致Android中的通信延迟

getSocketAddress()方法会导致延迟,从而导致Android中的通信延迟,android,udp,Android,Udp,我正在开发一个UDP响应程序来处理基本的SSDP命令。这段代码的目的是进行自动发现,因此,当服务器向特定组发送多播时,所有其他订阅的设备都应该向发送多播的主机和端口发回一个UDP数据包,宣布其存在。我的android设备接收和发送数据包都很正常,但由于从getSocketAddress()方法返回SocketAddress对象所需的时间太长,服务器超时,关闭侦听端口,并且从未从android设备返回数据包 这是我的密码: public void onCreate(Bundle saved

我正在开发一个UDP响应程序来处理基本的SSDP命令。这段代码的目的是进行自动发现,因此,当服务器向特定组发送多播时,所有其他订阅的设备都应该向发送多播的主机和端口发回一个UDP数据包,宣布其存在。我的android设备接收和发送数据包都很正常,但由于从getSocketAddress()方法返回SocketAddress对象所需的时间太长,服务器超时,关闭侦听端口,并且从未从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);
        }
    }
}
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秒