6

我必须使用 NIO 通过 ServerSocket 传输约 100MB 的数据,但我无法弄清楚如何做到这一点,而不会在任何地方传输中断/保持传输状态。

我的第一个想法是发送文件的大小,显然我无法发送那个大文件的大小,因为它甚至无法立即放入 RAM。然后我想,为什么不直接转移直到什么都没有收到,但那就是问题来了。

即使我一直在写服务器端数据

        FileChannel fc = new FileInputStream(f).getChannel();
        ByteBuffer buffer = ByteBuffer.allocate(1024);
        while(fc.read(buffer) > 0) {
            buffer.flip();
            while(channel.write(buffer) > 0);
            buffer.clear();
        }

但是因为文件传输必须中断一些时间不断读取数据并且在没有可用数据时中断是个坏主意。

我不知道我怎么可能告诉客户端是否还有可用的数据,而不必将每个数据片作为带有操作码等的新数据包发送,或者甚至有可能吗?

我也想知道是否有比下面更好的方法来发送整个缓冲区

while(channel.write(buffer) > 0);
4

3 回答 3

5

也许你正在寻找这个:

channel.transferFrom(0, fc.size(), fc);
于 2012-05-20T21:11:28.053 回答
4

通过缓冲区复制通道的正确方法如下:

while (in.read(buffer) >= 0 || buffer.position() > 0)
{
  buffer.flip();
  out.write(buffer);
  buffer.compact();
}

这会处理所有极端情况,包括读取长度!= 写入长度以及在输入末尾留下数据。

NB 用于阻塞模式。如果您处于非阻塞模式,则select()如果 read() 或 write() 返回零,则应返回循环。

于 2012-05-21T00:41:32.873 回答
0

如果您不能依赖套接字保持打开状态,则无法在您的协议中构建恢复并继续机制。至于告诉客户端需要多少字节,您可以在不将文件读入内存的情况下使用File.length.

于 2012-05-20T22:05:40.437 回答