我最近一直在编写带有非阻塞套接字的基于 Java NIO 的服务器,并且在写出数据时遇到了一些问题。我现在知道在某些情况下非阻塞写入无法写入 ByteBuffer 中的部分或全部字节。
我目前处理这种情况的方法是倒带或压缩缓冲区,然后尝试在下一次选择迭代中再次发送它。这无论如何都会导致显着的性能损失,我必须快速发送数据。
我曾尝试使用类似的东西:
ByteBuffer bb = ...;
SocketChannel sc = ...;
while(bb.remaining() > 0) {
sc.write(bb);
}
但问题在于它可能会写入 0 个字节并仍然退出 while 循环。我不知道为什么,但似乎 write() - 方法将达到 ByteBuffer 的限制,无论它是否实际发送了所有字节。
我在使用这种写入方法时遇到的另一个问题是,即使我没有尝试阻塞写入,它有时在重负载下也会导致缓冲区溢出异常。
我迫切需要一些关于如何正确执行阻塞写入以及什么条件可能导致 SocketChannel.write(ByteBuffer) 溢出缓冲区的建议(当达到限制时它不应该停止吗?)。
提前致谢。
编辑:我仍然没有找到 sc.write(bb) 将缓冲区中的位置设置为 bb.limit() 的原因,即使它写了 0 个字节。在写入尝试失败后,我唯一的办法仍然是倒带缓冲区。