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

时间:2011-10-27 23:25:07

标签: java sockets networking progress-bar outputstream

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

设置较低的缓冲区大小会稍微抵消差异,但仍然不正确。我尝试用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.
        }
    }

2 个答案:

答案 0 :(得分:4)

简而言之,考虑到你和“电线”本身之间的缓冲区数量,我认为你不能仅仅从“发送者”那里获得你正在寻找的那种准确的可见性。但是,我认为不重要。原因如下:

  1. 当字节被传递到网络堆栈时,字节计为“已发送”。当您发送少量字节(例如您的8K示例)时,这些字节将被缓冲和放大。 write()调用将很快返回。

  2. 一旦达到网络饱和状态,当各种网络缓冲区变满时,write()调用将开始阻塞 - 这样您就可以真正了解时间。

    < / LI>
  3. 如果你真的必须有某种“你收到了多少字节?”您必须让接收端通过带外机制定期发回数据(例如发光编码器建议)

答案 1 :(得分:2)

从套接字获取输入流,另一方面,当您将选择的字节写入磁盘时,将结果写入输出流。产生第二个线程来处理这些信息的读取,并将其链接到你的柜台。

您的变量是sent - 它是准确的。您需要的是receivedprocessed变量,为此您需要双向沟通。