我想连接一些字符串和一个jpeg二进制文件内容,以便在LINUX下用C发出一个http post请求。如果我使用正常的字符串操作,jpeg中的二进制内容一旦达到0x00就会终止。 (例如,如果我的HEX中的二进制文件是FF D8 FF C0 00 11 08 ...),在concat之后,二进制部分将以FF D8 FF C0结束。
有谁知道如何解决这个问题?语言在C.谢谢
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);
答案 0 :(得分:2)
以下是对您的问题的讨论以及我的提示,让我们看看它们。
AC字符串由0
终止,因此如果使用格式说明符%s
进行打印并传递带有嵌入式0
的(二进制)字符串,则第一个字符串将被识别为字符串终止符。
相反,请使用memcpy
,以便您可以通过explcitly传递大小。 假设poststr
的大小足以容纳所有内容,您应该这样做:
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
)。
我看到您正在构建多部分HTTP请求。 您可以对二进制数据进行编码,主要是BASE64或quoted-printable。两者都有C库,但您也可以在50-60行代码中实现相同的功能。您必须在标头中指定要使用的编码。有关语法参考,请参阅RFC 2045 §6.1。
在这种情况下,您的代码将正常工作,因为数据将编码为ASCII字符串。
答案 1 :(得分:0)
如果要将二进制数据附加到字符串上,请找到终止NULL
的位置,并将二进制数据存储到那里。例如:
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
字节,因此您不会遇到问题。
根据您用来发布帖子的库,您可能会发现它为您带来了艰苦的工作。