【发布时间】:2015-10-02 13:30:18
【问题描述】:
我目前正在用 C++ 编写一个小程序(在 Mac 上,其中包含一些 C 代码),需要从套接字检索二进制数据(效果很好),但我还需要切断 HTTP标题。
所以基本上,我连接到服务器,发送 HTTP GET 请求,然后获取 HTTP 200 标准标头,然后是二进制数据。我只需要二进制数据和标头的 Content-Length: 字段。
到目前为止我的功能:
void read_binary_data(ssize_t len,long long remain_data, FILE *fd, int sock){
char buffer[BUFSIZ];
int checker = 0;
int curr_position = 0;
while (((len = recv(sock, buffer, BUFSIZ, 0)) > 0) && (remain_data > 0)){
// if(checker == 4) => http header until curr_position+1, data starts at curr_position+2
for(char *pointer = buffer; curr_position <= len ; pointer++){
if(*pointer == '\r' || *pointer == '\n'){
checker++;
}
else{
checker = 0;
}
if(checker == 4){
break;
}
curr_position++;
}
fwrite(buffer, sizeof(char), len, fd);
remain_data -= len;
}
}
我最初会传递剩余数据 = 999 只是为了进入 while 循环(是的,我需要在那里进行一些错误处理,但目前这不是问题)。
现在for() 循环应该检查 HTTP 标头末尾的“\r\n\r\n”;我会这样吗?
然后,我如何将二进制数据从缓冲区复制到另一个缓冲区,然后使用 fwrite() 将其写入文件? (没有 HTTP 标头)
这对我来说已经足够了,但我想我也可以尝试使用提取的“内容长度:”信息“重新运行”这个函数来填充剩余数据。猜想在 while() 循环之后不再需要了完成。
但话又说回来,即使还有数据要读取,recv() 函数能否返回
总结一下:
- 我的
for()循环正确吗? - 如何从缓冲区中剪切 HTTP 标头?
- 我可以安全地删除“&& (remain_data > 0)”吗?
【问题讨论】:
-
您不需要从缓冲区中“剪切”HTTP 标头;您只需要从正文开始的位置开始写入(并从中减去标题的长度。您应该在尝试
recv()之前将测试放在remain_data上。为什么len是参数时你要做的第一件事是用来自recv()的值覆盖它? -
请注意,在第一次找到标头结尾标记后,您不再想查找它。目前,如果您读取第二个数据包,您将再次查找标头的结尾,这意味着您将忽略很多相关数据。
-
我将 len 作为参数传递,因为我首先在不同的程序中使用了这个函数,在运行 recv() 之前我知道数据长度
-
看到
int、ssize_t和long long“随机”混在一起让我的眼睛很痛。除了len之外的所有内容都应该是size_t。