我正在使用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()");
但是:
- 这将复制所有内容,包括所有 HTTP header 。您必须做更多的事情来读取和解析这些内容,而不是将它们写入文件。
- 如果传输编码被分块,这将不起作用,即使不是,它也会在流末尾遇到停顿,直到服务器关闭连接,由于 HTTP keep,它不会立即执行此操作-活。为了解决这个问题,您需要修改循环以仅读取与 Content-length header 中存在的字节数完全相同的字节。
解决这两个问题的方法是要么仔细阅读 RFC 2616 及其后续版本,要么使用 HTTP 客户端库,它已经为您完成了这一切。
关于c - 用 C 计算出 HTTP 服务器向客户端发送了多少字节,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46018820/