首页 > 解决方案 > GInputStream 并跟踪下载的总字节数

问题描述

我正在使用 GLib 堆栈学习 C,并且我有一个示例代码,它打开与主机的连接并通过读取 GInputStream 中的多个字节来下载文件。我试图通过在一秒钟后中断while循环然后将其打印到屏幕来跟踪每秒的总字节数。但是有时循环会在一秒以上(有时是 2-4 秒)后中断,我不明白为什么会这样。这是我的代码:

#define _POSIX_C_SOURCE 199309L

#include <stdio.h>
#include <libsoup/soup.h>
#include <time.h>

#define DOWNLOAD_SIZE 4096
#define DOWNLOAD_SPEED_LIMIT 819200L // bytes, 800kb

int main(void)
{

    SoupSession *session;
    SoupLogger *logger;

    session = soup_session_new_with_options (
        SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_CONTENT_SNIFFER,
        NULL
    );

    logger = soup_logger_new(SOUP_LOGGER_LOG_HEADERS, -1);
    soup_session_add_feature(session, (SoupSessionFeature *) logger);

    g_object_unref(logger);

    SoupMessage *message;
    GInputStream *stream;
    GError *error = NULL;
    char *url = "https://releases.ubuntu.com/20.04/ubuntu-20.04-desktop-amd64.iso";
    message = soup_message_new("GET", url);
    stream = soup_session_send(session, message, NULL, &error);

    const gchar *content_length = soup_message_headers_get_one(message->response_headers, "content-length");
    const gchar *content_type = soup_message_headers_get_one(message->response_headers, "content-type");
    gssize content_size = 0;
    if(content_length)
    {
        content_size = atol(content_length);
    }

    g_print("content-length: %u\n", content_size);
    g_print("content-type: %s\n", soup_message_headers_get_content_type(message->response_headers, NULL));

    GBytes *download_bytes;
    gssize downloaded_size = 0;
    gssize downloaded_size_per_iter = 0;

    guchar buff[DOWNLOAD_SIZE];

    if(content_length)
    {

        struct timespec start, current, end;

        // if content-length is known
        while(downloaded_size < content_size)
        {
            timespec_get(&start, TIME_UTC);
            end.tv_sec = start.tv_sec + 1;
            end.tv_nsec = start.tv_nsec;

            downloaded_size_per_iter = 0;
            while(1)
            {

                // download_bytes = g_input_stream_read_bytes(stream, DOWNLOAD_SIZE, NULL, NULL);
                // downloaded_size_per_iter +=  g_bytes_get_size(download_bytes);


                downloaded_size_per_iter += g_input_stream_read(
                    stream, &buff, DOWNLOAD_SIZE, NULL, NULL
                );
                timespec_get(&current, TIME_UTC);

                if(current.tv_sec == end.tv_sec && current.tv_nsec >= end.tv_nsec)
                    break;
                if(current.tv_sec > end.tv_sec)
                    break;
            }
            downloaded_size += downloaded_size_per_iter;
            printf("%ld %ld \n", start.tv_sec, start.tv_nsec);
            printf("%ld \n", (downloaded_size_per_iter/1024));   
            printf("%ld %ld\n", current.tv_sec, current.tv_nsec);
            printf("\n\n");           
        }
    }else
    {
        // content-length not known
    }
    return 0;
}

这是打印结果:https ://imgur.com/Nb3QVXD

那么我的代码有问题吗?不睡觉就看流不好吗?还是像ping等网络问题?我只是连接到 wifi 并且玩游戏时 ping 不是那么好

谢谢!

标签: cnetworkinggtkglibgobject

解决方案


推荐阅读