1

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

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

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

我只是担心不断清除数据并将其放入大型“结转”缓冲区可能会产生大量成本。如果有类似 SocketChannel.available() 的东西,我会喜欢它,但唯一最接近的替代方法是 Socket.getInputStream().available(),但该方法会阻塞。这样,如果可用数据多于缓冲区可以容纳的数据,我将扩展输入缓冲区(而不是大缓冲区)。不幸的是,我不能——所以我能想到的唯一解决方案就是我上面提到的那个。

我来这里是想问...你们中的任何一个聪明人有可能更好地解决这个问题吗?另外,我不想使用外部库——这只是个人喜好。

提前非常感谢!


我很抱歉。和一位亲密的朋友交谈后,我意识到一开始没有问题。解释很长,我就不解释了。我很抱歉。


发帖人注意:请永远不要删除问题文本。它为其他人提供指导。

4

1 回答 1

0

我已经实现了一个 NIO 套接字层,这样我就有了一个动态的缓冲区列表,这些缓冲区的大小都相同(无论你想要什么大小)。对于写入数据,一旦缓冲区被填满,就会将新缓冲区添加到列表中,并且继续将数据写入新缓冲区。当(假设是由您的代码)决定数据已准备好写入套接字时(基于 Selector 的回调),我将每个缓冲区写出,直到所有缓冲区都写入套接字。

我认为您可以对从 SocketChannel 进行读取做类似的事情(尽管由于读取要求不同,我没有在我的应用程序中实现它)。这是否是您的应用程序的更好解决方案取决于您。

我不完全确定我理解为什么你会得到一个异常......你为什么尝试读取超过缓冲区大小的内容?从套接字读取的任何逻辑都应确保您读取的内容不会超过缓冲区的大小。

于 2011-06-23T20:42:04.110 回答