c - 用 C 计算出 HTTP 服务器向客户端发送了多少字节

标签 c sockets

我正在使用C。

假设客户端使用连接的套接字通过 TCP 连接向 HTTP 服务器发送 GET 请求:

"GET /path/file.txt HTTP/1.0\r\n\r\n"

服务器应向客户端发送一个 header ,后跟请求的文件。不幸的是,该文件太大,无法存储在单个缓冲区中。所以我想一次从 sockID read() 一个 buf[BUF_SIZE] 将它们存储到输出文件中。为此,我需要服务器通过 sockID 发送的字节总数。这就是我陷入困境的地方......我尝试了以下方法来获取字节数:

struct stat st;
int err = fstat(sockID, & st);
if(err == -1)
{
  fprintf(stderr, "fstat: [errno %d] %s\n", errno, strerror(errno));
  exit(EXIT_FAILURE);
}
printf("size: %jd\n", st.st_size);
>>>> return: 0 bytes

我也尝试过:

lseek(sockID, 0, SEEK_END)
>>>> return: Illegal lseek

最后,我研究了使用 getsockopt(),但经过我最大的努力,我仍然对这个函数的使用方式感到非常困惑。

我做错了什么?对于我的问题有更简单的解决方案吗?

谢谢。

最佳答案

So I want to instead read() from the sockID one buf[BUF_SIZE] at a time to store them into an output file. For that, I need the total number of bytes the server sent over sockID.

不,你不知道。简而言之,您只需要规范的复制循环:

char buffer[8192]:  // or more, any size over zero will work
int count;
while ((count = recv(sockFD, buffer, sizeof buffer, 0)) > 0)
{
    if (write(fileFD, buffer, count) == -1)
    {
        // write error
        perror("write()");
        break;
    }
}
if (count == -1)
    // terminated by receive error
    perror("recv()");

但是:

  1. 这将复制所有内容,包括所有 HTTP header 。您必须做更多的事情来读取和解析这些内容,而不是将它们写入文件。
  2. 如果传输编码被分块,这将不起作用,即使不是,它也会在流末尾遇到停顿,直到服务器关闭连接,由于 HTTP keep,它不会立即执行此操作-活。为了解决这个问题,您需要修改循环以仅读取与 Content-length header 中存在的字节数完全相同的字节。

解决这两个问题的方法是要么仔细阅读 RFC 2616 及其后续版本,要么使用 HTTP 客户端库,它已经为您完成了这一切。

关于c - 用 C 计算出 HTTP 服务器向客户端发送了多少字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46018820/

相关文章:

c - 用FD_SET制作读写集,用于在C中发送和接收数据

c - 尝试从 recv() 字符数组解析十进制 dstAddr.sin_addr.s_addr

c - 在c中接收原始以太网数据包

c - 将 'C' 中的字符数组拆分为 CSV

c - sizeof(<variable>) 而不是 sizeof(<type>) 总是安全的吗?

c# - Web 服务可以在 asp.net 中运行,但不能在 IIS 中运行

c++ - 发送没有文件描述符的文件

python - 套接字程序崩溃后无法绑定(bind)到地址

c - Getopt() 错误检查

python - 在 C 程序中嵌入 Python 模块时,如何将 C 结构传递到 Python 中