Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/sockets/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
测量通过Java套接字写入的实际字节_Java_Sockets_Networking_Progress Bar_Outputstream - Fatal编程技术网

测量通过Java套接字写入的实际字节

测量通过Java套接字写入的实际字节,java,sockets,networking,progress-bar,outputstream,Java,Sockets,Networking,Progress Bar,Outputstream,我写了一个小程序,可以从一个客户机向另一个客户机发送/接收文件。我已经为接收者和客户端设置了progressbar,但问题是发送者的progressbar完成速度似乎比实际传输快得多。问题在于它如何计算已写入的字节数。我假设它是计算我读入缓冲区的字节数,而不是通过网络发送的字节数,那么我如何才能找到这个问题的解决方案呢?接收方正在以正确的速率计算其接收的字节,但发送方没有正确地完成其部分 设置较低的buffersize会稍微抵消差异,但仍然不正确。我尝试用CountingOutputStream

我写了一个小程序,可以从一个客户机向另一个客户机发送/接收文件。我已经为接收者和客户端设置了progressbar,但问题是发送者的progressbar完成速度似乎比实际传输快得多。问题在于它如何计算已写入的字节数。我假设它是计算我读入缓冲区的字节数,而不是通过网络发送的字节数,那么我如何才能找到这个问题的解决方案呢?接收方正在以正确的速率计算其接收的字节,但发送方没有正确地完成其部分

设置较低的buffersize会稍微抵消差异,但仍然不正确。我尝试用CountingOutputStream包装outputstream,但它返回的结果与下面的代码片段相同。传输最终正确完成,但我需要正确的“发送”值来更新我的progressbar,就像在接收端实际接收并写入光盘一样。我已经包含了一个非常精简的代码片段,它代表了我计算传输字节的方式。任何解决方案的例子都会非常有用

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.
        }
    }

从套接字获取输入流,另一方面,当您将所选字节写入磁盘时,将结果写入输出流。生成第二个线程来处理此信息的读取,并将其链接到您的计数器


您的变量已发送——准确无误。您需要的是一个
接收的
处理的
变量,为此您需要双向通信。

简言之,考虑到您和“线路”本身之间的缓冲区数量,我认为您无法从“发送方”端获得您想要的那种准确可见性。但我也不认为这有什么关系。原因如下:

  • 当字节被交给网络堆栈时,它们被计为“已发送”。当您发送少量字节(例如8K示例)时,这些字节将被缓冲&write()调用将快速返回

  • 一旦达到网络饱和,write()调用将随着各种网络缓冲区变满而开始阻塞,这样您就可以真正了解时间

  • 如果你真的必须有某种形式的“你收到了多少字节?”你必须让接收端通过带外机制(如glowcoder建议的)周期性地将数据发回


  • 在output.write()调用之后,您可以尝试对输出流调用flush(),这将刷新缓冲区,并实际导致数据通过网络发送。但是,缓冲区是用来提高性能的,如果继续使用flush(),性能可能会受到影响。@prunge flush()实际上不会导致数据通过网络发送,事实上,未修饰的套接字输出流上的flush()什么都不做。@EJP您是对的,查看源代码可以发现flush()什么都不做。我想减少延迟的方法是在套接字上设置tcpnodelay(false),这将关闭。