Java的; NIO - 从SocketChannel读取大量数据

时间:2011-06-23 19:43:55

标签: java nio socketchannel

我正在编写一个非常简单的网络库,我可以在将来用于其他项目。现在,我在处理阅读操作时遇到了麻烦。我有一个类负责处理来自SocketChannels的事件,它还包含输入和输出缓冲区。要初始化缓冲区,您需要定义它的大小。因此,默认情况下,所有缓冲区的大小都是1024字节。

我遇到的问题是,如果我读取的数据包大于1024字节,我将得到一个异常。这可以通过默认分配一个更大的缓冲区来修复(例如,2048字节,而不是1024),但这似乎很简单,我特别不喜欢这个解决方案。

我想出的解决方案是创建一个非常大的直接静态缓冲区(它是Short.MAX_VALUE大)。来自SocketChannels的所有数据都将被读入大缓冲区,然后被复制到较小的缓冲区中(如果它们不适合数据,则扩展缓冲区。)

我只是担心不断清算并将数据放入大的“结转”缓冲区可能会有很大的成本。如果有类似SocketChannel.available()的东西,我会喜欢它,但唯一最接近的选择是Socket.getInputStream()。available(),但该方法阻止。这样我就可以扩展输入缓冲区(而不是大缓冲区),如果有更多可用数据而不是缓冲区可以容纳的数据。不幸的是,我不能 - 所以我能想到的唯一解决方案是我上面提到的解决方案。

我来这里问...你们中有谁聪明的人有更好的解决方案吗?此外,我不想使用外部库 - 这只是个人偏好。

提前多多感谢!


我道歉。在与一位好朋友交谈之后,我意识到开始没有问题。这是一个很长的解释,所以我不会解释它。我道歉。


海报注意:请不要删除问题文本。它可以作为其他人的指导。

1 个答案:

答案 0 :(得分:0)

我已经实现了一个NIO套接字层,这样我就拥有了一个动态的缓冲区列表,这些缓冲区的大小都是相同的(你想要的大小)。对于写入数据,一旦填充了缓冲区,就会向列表中添加一个新缓冲区,并继续将数据写入新缓冲区。当(通过你的代码,据称)确定数据已准备好写入套接字(基于Selector的回调)时,我会写出每个缓冲区,直到所有缓冲区都写入套接字。

我认为你可以从SocketChannel读取类似的东西(虽然我没有在我的应用程序中实现它,因为阅读的要求不同)。这对您的应用程序来说是否是更好的解决方案取决于您。

我不完全确定我明白为什么你会得到一个异常...为什么你试着读取超过缓冲区的大小?无论从套接字读取什么逻辑,都应确保读取的内容不超过缓冲区的大小。