【发布时间】:2022-01-23 17:53:07
【问题描述】:
我正在尝试使用用 C (Windows) 编写的客户端程序将二进制文件发布到 Web 服务器。我对套接字编程很陌生,所以尝试使用带有纯文本消息的multipart/form-data 和基于文本的文件(.txt、.html、.xml)的 POST 请求。这些似乎工作正常。但是在尝试发送 PNG 文件时,我遇到了一些问题。
以下是我读取二进制文件的方法
FILE *file;
char *fileName = "download.png";
long int fileLength;
//Open file, get its size
file = fopen(fileName, "rb");
fseek(file, 0, SEEK_END);
fileLength = ftell(file);
rewind(file);
//Allocate buffer and read the file
void *fileData = malloc(fileLength);
memset(fileData, 0, fileLength);
int n = fread(fileData, 1, fileLength, file);
fclose(file);
我确认所有字节都被正确读取。
这就是我形成邮件标题和正文的方式
//Prepare message body and header
message_body = malloc((int)1000);
sprintf(message_body, "--myboundary\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Disposition: form-data; name=\"myFile\"; filename=\"%s\"\r\n\r\n"
"%s\r\n--myboundary--", fileName, fileData);
printf("\nSize of message_body is %d and message_body is \n%s\n", strlen(message_body), message_body);
message_header = malloc((int)1024);
sprintf(message_header, "POST %s HTTP/1.1\r\n"
"Host: %s\r\n"
"Content-Type: multipart/form-data; boundary=myboundary\r\n"
"Content-Length: %d\r\n\r\n", path, host, strlen(message_body));
printf("Size of message_header is %d and message_header is \n%s\n", strlen(message_header), message_header);
连接和发送部分也可以正常工作,因为请求被正确接收。但是,收到的 png 文件格式不正确。
如果我在 printf 中使用 %s,终端会为 fileData 打印以下内容
ëPNG
我四处搜索,发现二进制数据的行为不像字符串,因此 printf/sprintf/strcat 等不能用于它们。由于二进制文件嵌入了空字符,%s 将无法正确打印。看起来这就是 fileData 只打印 PNG 标头的原因。
目前,我向服务器发送了两个 send() 请求。一个带有页眉,另一个带有正文和页脚。这适用于基于文本的文件。为避免将sprintf 用于二进制数据,我尝试发送一个请求标头、一个请求二进制数据(正文)和一个请求页脚。这似乎也不起作用。
另外,发现memcpy 可用于将二进制数据附加到普通字符串。那也没有用。这是我的尝试(不确定我的实现是否正确)。
sprintf(message_body, "--myboundary\r\n"
"Content-Disposition: form-data; name=\"text1\"\r\n\r\n"
"text default\r\n"
"--myboundary\r\n"
"Content-Type: application/octet-stream\r\n"
"Content-Disposition: form-data; name=\"myFile\"; filename=\"%s\"\r\n\r\n", fileName);
char *message_footer = "\r\n--myboundary--";
char *message = (char *)malloc(strlen(message_body) + strlen(message_footer) + fileLength);
strcat(message, message_body);
memcpy(message, fileData, fileLength);
memcpy(message, message_footer, strlen(message_footer));
我不知道如何发送需要附加字符串(标题)、二进制数据(有效负载)、字符串(页脚)的有效负载。
任何用于发送整个文件的建议/指针/参考链接将不胜感激。谢谢!
【问题讨论】:
-
您可以从 StackOverflow 上的 post 开始阅读
标签: c http post multipartform-data binaryfiles