【问题标题】:C cut char arry and save binary data from socketC切割char数组并从套接字保存二进制数据
【发布时间】: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() 之前我知道数据长度
  • 看到intssize_tlong long“随机”混在一起让我的眼睛很痛。除了len 之外的所有内容都应该是size_t

标签: c sockets binary buffer


【解决方案1】:

for循环正确吗?

不,不是

即使您有 "\r\r\r\r" 或两个字符的所有组合,您的 if(checker == 4) 也可能为真

你可以写

char *pointer = buffer;
int remaining = len;
for(; remaining ; remaining--)
{
    if ((*pointer == '\r') && (remaining > 3))
    {
        if (!strncmp(pointer, "\r\n\r\n", 4))
        {
           pointer+=4;
           remaining-=4;
           break;
        }
    }

    pointer++;
}

如何从缓冲区中剪切 HTTP 标头?

我不确定我会得到你。 如果您需要复制"\r\n\r\n" 之后的所有数据,您可以这样做,基于上面的代码:

fwrite(pointer, sizeof(char), remaining, fd);

我可以安全地删除 '&& (remain_data > 0)' 吗?

如果发件人为您做,您可以:如果发件人向您发送您需要的正确数量的数据。

【讨论】:

  • 好的,我得到了正确的 for(),ty。现在,当将剩余和指针传递给 fwrite() 时,fwrite 是否从指针的开头(在缓冲区中的 '\r\n\r\n' 之后)直到指针/缓冲区的结尾,或者从缓冲区的开头直到剩余?
  • @user1641602 我编辑了。这样,它开始从"\r\n\r\n" 之后的字符复制remaining 字节
  • @user1641602 如果足够了,请不要忘记关闭已回答的问题。
猜你喜欢
  • 1970-01-01
  • 2018-05-31
  • 2017-07-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-03-16
  • 2014-05-27
  • 2012-08-23
相关资源
最近更新 更多