测量通过Java套接字写入的实际字节
我写了一个小程序,可以从一个客户机向另一个客户机发送/接收文件。我已经为接收者和客户端设置了progressbar,但问题是发送者的progressbar完成速度似乎比实际传输快得多。问题在于它如何计算已写入的字节数。我假设它是计算我读入缓冲区的字节数,而不是通过网络发送的字节数,那么我如何才能找到这个问题的解决方案呢?接收方正在以正确的速率计算其接收的字节,但发送方没有正确地完成其部分 设置较低的buffersize会稍微抵消差异,但仍然不正确。我尝试用CountingOutputStream包装outputstream,但它返回的结果与下面的代码片段相同。传输最终正确完成,但我需要正确的“发送”值来更新我的progressbar,就像在接收端实际接收并写入光盘一样。我已经包含了一个非常精简的代码片段,它代表了我计算传输字节的方式。任何解决方案的例子都会非常有用测量通过Java套接字写入的实际字节,java,sockets,networking,progress-bar,outputstream,Java,Sockets,Networking,Progress Bar,Outputstream,我写了一个小程序,可以从一个客户机向另一个客户机发送/接收文件。我已经为接收者和客户端设置了progressbar,但问题是发送者的progressbar完成速度似乎比实际传输快得多。问题在于它如何计算已写入的字节数。我假设它是计算我读入缓冲区的字节数,而不是通过网络发送的字节数,那么我如何才能找到这个问题的解决方案呢?接收方正在以正确的速率计算其接收的字节,但发送方没有正确地完成其部分 设置较低的buffersize会稍微抵消差异,但仍然不正确。我尝试用CountingOutputStream
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.
}
}
从套接字获取输入流,另一方面,当您将所选字节写入磁盘时,将结果写入输出流。生成第二个线程来处理此信息的读取,并将其链接到您的计数器
您的变量已发送——准确无误。您需要的是一个
接收的
或处理的
变量,为此您需要双向通信。简言之,考虑到您和“线路”本身之间的缓冲区数量,我认为您无法从“发送方”端获得您想要的那种准确可见性。但我也不认为这有什么关系。原因如下:
在output.write()调用之后,您可以尝试对输出流调用flush(),这将刷新缓冲区,并实际导致数据通过网络发送。但是,缓冲区是用来提高性能的,如果继续使用flush(),性能可能会受到影响。@prunge flush()实际上不会导致数据通过网络发送,事实上,未修饰的套接字输出流上的flush()什么都不做。@EJP您是对的,查看源代码可以发现flush()什么都不做。我想减少延迟的方法是在套接字上设置tcpnodelay(false),这将关闭。