3

我正在使用带有字节缓冲区的文件通道通过网络发送数据包。我的问题是,当文件通道读取最后几个字节时,即使我在写入后清除字节缓冲区,它也会从先前读取的字节中附加最后一位数据。

例如,

字节缓冲区大小 = 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
}
4

1 回答 1

3
  1. 使用DatagramChannel这种方式真的永远不会奏效。您只是发送文件的块,这些文件可能会或可能不会到达,或者以任何顺序到达两次或更多。使用 TCP。

  2. 即使它确实神奇地起作用,而且我怀疑“省略的代码”或接收代码中还有更多错误:

    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()缓冲区已清空。

  3. 如果不是,DatagramChannel您应该使用比 512 大得多的缓冲区,例如 8192。

于 2014-11-17T22:12:32.857 回答