IOException“Socket已关闭:未知的socket_descriptor”,使用带有Google App Engine的java.net.DatagramSocket

时间:2015-05-19 01:32:42

标签: java sockets google-app-engine

我正在使用java.net.DatagramSocket从Google App Engine servlet将UDP数据包发送到statsd服务器。这通常有效;但是,我们会定期看到以下异常:

IOException - Socket is closed: Unknown socket_descriptor..

发生这些IOExceptions时,调用DatagramSocket.isClosed()会返回false

这个问题经常发生,它很有用,虽然我已经实现了一些解决方法(分配一个新的套接字并使用DeferredTask队列重试),但理解这些错误的底层原因会很好。

Google docs提到,“套接字可以在2分钟不活动后回收;任何套接字操作都会使套接字保持活动状态2分钟。”我不清楚这将如何影响UDP数据报;但是,我怀疑的是,这与GAE实例生命周期有某种关系。

我的代码(已清理和提取)看起来像:

DatagramSocket _socket;

void init() {
    _socket = new DatagramSocket();
}

void send() {
    DatagramPacket packet = new DatagramPacket(<BYTES>, <LENGTH>, <HOST>, <PORT>); 
    _socket.send(packet);
}

感谢对此的任何反馈!

1 个答案:

答案 0 :(得分:0)

解决此问题的方法只是使用几个辅助方法管理单个静态DatagramSocket实例getSocket()releaseSocket()以释放通过release方法抛出IOExceptions的套接字,然后分配下次通过get方法访问。此代码中未显示重试逻辑,以重试失败的socket.send()。在负载测试下,这似乎可靠地工作。

try {

    DatagramPacket packet = new DatagramPacket(<BYTES>, <LENGTH>, <HOST>, <PORT>);

    getSocket().send(packet);

} catch (IOException ioe) {

    releaseSocket();

}