如何管理打开的数据报套接字以避免超过最大值?
Posted
技术标签:
【中文标题】如何管理打开的数据报套接字以避免超过最大值?【英文标题】:How do I manage open datagram sockets to avoid exceeding maximum? 【发布时间】:2016-01-14 17:24:23 【问题描述】:我正在开发一些使用大量数据报套接字的代码。如果不仔细编码,这个数字可能会超过 jvm 允许的最大值。使用-Dsun.net.maxDatagramSockets=x
并不总是一种选择。我有这样的代码:
/* opening this channel will bring us to the limit--the maximum allowed by the JVM */
DatagramChannel channel1 = DatagramChannel.open();
/* do some stuff with channel1 */
/* Close channel1, and dereference it */
channel1.close();
channel1 = null;
/* this throws SocketException */
DatagramChannel channel2 = DatagramChannel.open();
分享DatagramChannel
s(即使用receive()
)可能是另一种选择,但知道这里发生了什么会很有用。
编辑:在实际代码中缩小问题范围后,我发现代码 sn-p 过于简化。这里的想法是,在达到DatagramChannel
s 的最大数量后,只有在另一个关闭时才会创建一个新的。但是,我处理的是SocketChannel
s 和DatagramChannel
s 的混合体,问题是即使我在处理完这些频道时在频道上调用close()
,我必须确保频道我刚刚关闭的是DatagramChannel
(而不是SocketChannel
),然后再创建另一个。只是一个疏忽。
【问题讨论】:
你看过AutoCloseable
和[try-with-resources](http://docs.oracle.com/javase/tutorial/essential/exceptions/tryResourceClose.html)
吗?但我不明白为什么上面的channel2
应该在“channel1”已关闭时抛出异常......
谢谢。 DatagramChannel
实现了Closeable
,而try-with-resources
只是确保在try
块完成之前对资源调用close()
(即finally
会做什么)。据我所知,问题中的代码与提供的代码相同。
对,那么如果channel1.close()
成功,为什么channel2 = DatagramChannel.open()
会抛出异常?
这正是我想知道的:)。我不知道这是因为垃圾收集延迟还是其他原因,以及可能建议解决它的方法。
垃圾回收无关。在该主题上,甚至不需要channel1 = null
。我怀疑问题出在其他地方。以下 Ira 的建议可能有用。否则我会将DatagramChannel
包装在另一个类中,在那里我打开和关闭登录。我怀疑你没有关闭它们。请使用异常输出更新问题。
【参考方案1】:
处理此问题的最佳方法是使用一组可重复使用的池化套接字。我建议使用 netty 之类的框架,以避免必须自己实现所有细节。
【讨论】:
以上是关于如何管理打开的数据报套接字以避免超过最大值?的主要内容,如果未能解决你的问题,请参考以下文章
如何将数据从 Android 中的数据报套接字发送到 Node js 服务器?
查找最大 UDP 有效负载——python 套接字发送/发送