c - 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(¤t, 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 不是那么好
谢谢!
解决方案
推荐阅读
- ios - 将 uitextfield 3 中的光标向右移动
- mongodb - _id 字段在 mongodb 中真的是独一无二的吗?
- android - Google Api 错误:禁止:调用者没有权限 - 调用者没有权限
- c# - 保存更改的序列化值(Unity Editor C#)
- ubuntu - 如何使用 certbot 自动更新 TLS 证书?
- android - 显示天气信息的应用程序在模拟器上运行,而不是在实际手机上运行
- java - 无法通过 docker 创建 h2 表(sprint boot 应用程序)
- powerbi - power bi:关闭报表头而不改变报表链接
- json - 如何以角度访问 JSON 字段?
- flutter - 如何在flutter中动态地将内部导航添加到pdf