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

发布于 2024-12-12 02:39:44 字数 842 浏览 0 评论 0原文

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

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

I have written a small program which send/receives files from one client to another. I've set up progressbars for both the receiver and the client, but the problem is that the sender seems to have his progressbar finish much quicker than the actual transfer. The problem lies with the how it calculates how many bytes that have been written. I'm assuming it's counting how many bytes I've read into buffer, rather than bytes that were sent through the network, so how can I find a solution to this problem? The receiver is calculating his received bytes at a correct rate, but the sender is not doing his part correctly.

Setting a lower buffersize offsets the difference a bit, but it's still not correct. I've tried wrapping the outputstream with a CountingOutputStream, but it returns the same result as the code snippet below. The transfer eventually completes correctly, but I need the proper "sent" values to update my progressbar, as in what was actually received and written to disc at the receiver side. I've included a very stripped down code snippet which represents my way of calculating transferred bytes. Any examples of a solution would be very helpful.

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

清醇 2024-12-19 02:39:44

简而言之,考虑到您和“线路”本身之间的缓冲区数量,我认为您无法仅从“发送方”一侧获得所需的准确可见性。但我认为这并不重要。原因如下:

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

  2. 达到网络饱和,随着各种网络缓冲区变满,您的 write() 调用将开始阻塞 - 因此您将真正了解时间。

  3. 如果您确实必须有某种“您收到了多少字节?” 如果你

In short, I don't think you can get the sort of accurate visibility you're looking for solely from the "sender" side, given the number of buffers between you and the "wire" itself. But also, I don't think that matters. Here's why:

  1. Bytes count as "sent" when they are handed to the network stack. When you are sending a small number of bytes (such as your 8K example) those bytes are going to be buffered & the write() calls will return quickly.

  2. Once you're reached network saturation, your write() calls will start to block as the various network buffers become full - and thus then you'll get a real sense of the timings.

  3. If you really must have some sort of "how many bytes have you received?" you'll have to have the receiving end send that data back periodically via an out-of-band mechanism (such as suggested by glowcoder)

鱼窥荷 2024-12-19 02:39:44

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

您的变量已发送 - 它是准确的。您需要的是一个receivedprocessed 变量,为此您需要双向通信。

Get the input stream from the socket, and on the other side, when you've written a selection of bytes to disk, write the result to the output stream. Spawn a second thread to handle the reading of this information, and link it to your counter.

Your variable is sent - it is accurate. What you need is a received or processed variable, and for that you will need two-way communication.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文