首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有二进制的凹字串:当命中0x00时二进制内容被截断

带有二进制的凹字串:当命中0x00时二进制内容被截断
EN

Stack Overflow用户
提问于 2014-01-21 20:45:34
回答 2查看 180关注 0票数 0

我想连接一些字符串和jpeg二进制文件内容,以便在LINUX下以C语言发出http请求。如果我使用正常的字符串操作,jpeg中的二进制内容一旦命中0x00就会终止。(例如,如果我的二进制文件在HEX中是FF D8 FF C0 00 11 08.),在连接之后,二进制部分将以FF D8 FF C0结束。

有人知道如何解决这个问题吗?语言是C语言,谢谢

代码语言:javascript
复制
 fp = fopen(filename, "rb")
 fseek(fp, 0, SEEK_END);
 fileLen = ftell(fp);
 fseek(fp, 0, SEEK_SET);
 buffer = (char *)malloc(fileLen);
 fread(buffer, fileLen, 1, fp);  

 //now buffer has the content of the JPEG image

 //next combine both string and binary together to make a http post request

 snprintf(poststr, MAXSUB,
             "--%s\r\nContent-Disposition: form-data;"
             "name=\"datafile\"; filename=\"%s\"\r\nContent-Type: image/jpeg\r\n\r\n"
             "%s\r\n"
             "--%s\r\n"
             "Content-Disposition: form-data; name=\"boxkey\"\r\n\r\n%s\r\n"
             "--%s--", boundary, filename, buffer, boundary, key, boundary);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-01-21 20:54:06

这是关于你的问题的讨论和我的一个建议,让我们来看看它们。

复制二进制数据

C字符串由0终止,因此如果使用格式说明符%s打印并传递带有嵌入式0的(二进制)字符串,则第一个字符串将被识别为字符串终止符。

相反,使用memcpy,这样您就可以显式地传递大小。假设poststr的大小足以容纳一切,那么您应该这样做:

代码语言:javascript
复制
int headLength = snprintf(poststr, MAXSUB,
         "--%s\r\nContent-Disposition: form-data;"
         "name=\"datafile\"; filename=\"%s\"\r\nContent-Type: image/jpeg\r\n\r\n"
     boundary, filename
);

// Declarations added for clarity, you can remove them
char *bodystr = poststr + headLength;
char *footerstr = bodystr + bufferLength;

// Copy binary here
memcpy(bodystr, buffer, bufferLength);

snprintf(footerstr, MAXSUB,
         "--%s\r\n"
         "Content-Disposition: form-data; name=\"boxkey\"\r\n\r\n%s\r\n"
         "--%s--", boundary, key, boundary
);

请考虑结果字符串将嵌入0,因此您必须计算“实际”长度并将其保存在某个位置(strlen在第一个嵌入0时也会停止)。

在mime/多部分消息中编码二进制数据

我看到您正在构建一个多部分HTTP请求。您可以对二进制数据进行编码,大部分为BASE64或可引用-可打印。这两种代码都有C库,但您也可以在50-60行代码中实现相同的功能。您必须指定在标头中使用的编码。有关语法引用,请参见RFC 2045§6.1

在这种情况下,您的代码将运行,因为数据将编码为ASCII字符串。

票数 2
EN

Stack Overflow用户

发布于 2014-01-21 20:58:27

如果要将二进制数据附加到字符串中,请查找终止NULL的位置,并将二进制数据添加到该字符串上。例如:

代码语言:javascript
复制
void
appendBinaryToString (char *string, void *binary, size_t length)
{
    /* IMPORTANT
     * Ensure the memory allocated for string has sufficient space
     * to permit the binary to be copied in
     */

    /* Offset of NULL is at strlen(string) */
    memcpy (string + strlen(string), binary, length;
}

但是,请注意,输出将是长度为length + strlen(string)的二进制字符数组,而不是以零结尾的字符串。这就是你想要的吗?如果是这样,您可能会更好地考虑这样一个问题:“如何将字符串的二进制内容和另一个二进制blob复制到相邻的内存位置?”我提到这一点的原因是,我认为您正在尝试将二进制数据复制到poststr中,然后将其作为字符串处理;也许您确实希望对数据(base64或类似的)进行编码,然后添加;由于编码的数据不包括NUL字节,因此不会出现问题。

取决于你使用哪个库来写帖子,你可能会发现它为你做了艰苦的工作。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21268750

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档