我编写了一个小程序,用于从一个客户端向另一个客户端发送/接收文件。我为接收器和客户端设置了进度条,但问题是发送方似乎比实际传输更快地完成了进度条。问题在于它如何计算已写入的字节数。我假设它正在计算我读入缓冲区的字节数,而不是通过网络发送的字节数,那么我该如何找到解决这个问题的方法呢?接收器正在以正确的速率计算他接收的字节,但发送者没有正确地做他的部分。
设置较低的缓冲区大小会稍微抵消差异,但仍然不正确。我尝试用CountingOutputStream包装outputstream,但它返回与下面的代码片段相同的结果。传输最终正确完成,但我需要正确的“已发送”值来更新我的进度条,就像在接收器端实际接收并写入光盘一样。我已经包含了一个非常简化的代码片段,它代表了我计算传输字节的方法。任何解决方案的例子都会非常有用。
try
{
int sent = 0;
Socket sk = new Socket(ip, port);
OutputStream output = sk.getOutputStream();
FileInputStream file = new FileInputStream(filepath);
byte[] buffer = new byte[8092];
while ((bytesRead = file.read(buffer)) > 0)
{
output.write(buffer, 0, bytesRead);
sent += bytesRead;
System.out.println(sent); // Shows incorrect values for the actual speed.
}
}
答案 0 :(得分:4)
简而言之,考虑到你和“电线”本身之间的缓冲区数量,我认为你不能仅仅从“发送者”那里获得你正在寻找的那种准确的可见性。但是,我认为不重要。原因如下:
当字节被传递到网络堆栈时,字节计为“已发送”。当您发送少量字节(例如您的8K示例)时,这些字节将被缓冲和放大。 write()调用将很快返回。
一旦达到网络饱和状态,当各种网络缓冲区变满时,write()调用将开始阻塞 - 这样您就可以真正了解时间。
< / LI>如果你真的必须有某种“你收到了多少字节?”您必须让接收端通过带外机制定期发回数据(例如发光编码器建议)
答案 1 :(得分:2)
从套接字获取输入流,另一方面,当您将选择的字节写入磁盘时,将结果写入输出流。产生第二个线程来处理这些信息的读取,并将其链接到你的柜台。
您的变量是sent
- 它是准确的。您需要的是received
或processed
变量,为此您需要双向沟通。