2

我实现了 STUN 客户端,它在指定的时间段内向 STUN 服务器发送请求,并在此期间监听来自 STUN 服务器的请求:

try {

  byte[] respData = new byte[1024];
  DatagramPacket bRespPacket = new DatagramPacket(respData, respData.length);
  datagramSocket.setSoTimeout(timeout);
  datagramSocket.receive(bRespPacket); 
  processReceivedData(bRespPacket.getData());

  } catch (Exception e){}

如果设备进入待机模式(屏幕关闭时),程序执行将冻结在 datagramSocket.receive() 上,并且在屏幕解锁之前不会抛出 SocketTimeoutException。当屏幕解锁时,成功抛出 SocketTimeoutException 并继续执行程序。这种行为的原因是什么?

UPD: 如果设备空闲程序执行在 datagramSocket.receive 方法上冻结并且没有接收任何传入数据。我尝试使用 WifiLock 但没有结果。

UPD 2: 如果我使用 WakeLock 一切正常,但我想这不是一个好方法

4

1 回答 1

1

为了安全起见,如果屏幕熄灭,Android 会关闭组件。我想这会以某种方式冻结您的代码执行。当 Android 关闭 WiFi 时,您的套接字可能会受到干扰。

作为一种快速解决方法,您可以尝试使用 Wifi 锁来防止 Android 出现这种行为。如果这解决了您的问题,您应该考虑在没有 WiFi 锁定的情况下以不同的方式实现它,即检查设备的连接,如果它已更改,则重新创建您的套接字。

http://developer.android.com/reference/android/net/wifi/WifiManager.WifiLock.html

编辑:

它自己尝试了一下,做了一个小例子。结果是即使屏幕关闭并等待几分钟,我在接收 UDP 包时也没有问题。我在接收时播放声音并且屏幕关闭时播放有点生涩,这证明手机处于待机模式。

我只是从活动中直接在一个新线程中启动一个套接字,然后在那里等待 socket.receive。没什么特别的:

DatagramSocket socket = new DatagramSocket(port);

byte[] buf = new byte[256];

while(true) {
DatagramPacket packet = new DatagramPacket(buf, buf.length);

socket.receive(packet);

    // doing something with the data...
setOutputText(new String(buf));

}

我在 Galaxy Nexus 上对其进行了测试。也许您可以提供有关您的问题的更多详细信息?

于 2012-03-14T16:53:42.167 回答