我正在使用带有字节缓冲区的文件通道通过网络发送数据包。我的问题是,当文件通道读取最后几个字节时,即使我在写入后清除字节缓冲区,它也会附加以前读取的字节的最后一位数据。
例如
字节缓冲区大小 = 512对于最后一次迭代,要发送的剩余字节为 372。它读取最后 372 个字节,但也在其末尾附加另一个 140 个字节 (512-372),并且看起来最后 140 个字节来自之前发送的 512 个字节。
这是我的代码:
ByteBuffer bBuffer = ByteBuffer.allocate(512);
while (fChannel.read(bBuffer) > 0) {
bBuffer.flip();
datagramChannel.write(bBuffer);
bBuffer.clear();
//omitted code
}
-
以这种方式使用
DatagramChannel
真的是行不通的。您只是发送文件块,这些文件块可能会也可能不会到达,或者以任何顺序到达两次或更多。使用 TCP。 -
即使它确实神奇地工作,并且我怀疑"省略的代码"或接收代码中还有其他错误:
while (fChannel.read(bBuffer) > 0) { bBuffer.flip(); datagramChannel.write(bBuffer); bBuffer.clear(); //omitted code }
Java 中通道之间的复制循环的正确版本如下:
while (fChannel.read(buffer) > 0 || buffer.position() > 0) { buffer.flip(); datagramChannel.write(bBuffer); buffer.compact(); }
请注意,您必须在缓冲区中仍有任何内容(
buffer.position() > 0
)时继续写入,并且您必须compact()
而不是clear()
,以免假设write()
清空缓冲区。 -
如果不是
DatagramChannel
则应使用大于 512 的缓冲区,例如 8192。