使用 C 套接字在 HTTP 响应中发送二进制文件 [英] Send binary file in HTTP response using C sockets
问题描述
我正在尝试在 http 响应中发送二进制文件(png 图像).
I`m trying to send a binary file (png image) in http response.
FILE *file;
char *buffer;
int fileLen;
//Open file
file = fopen("1.png", "rb");
if (!file)
{
return;
}
//Get file length
fseek(file, 0, SEEK_END);
fileLen=ftell(file);
fseek(file, 0, SEEK_SET);
//Allocate memory
buffer=(char *)malloc(fileLen+1);
if (!buffer)
{
fprintf(stderr, "Memory error!");
fclose(file);
return;
}
//Read file contents into buffer
fread(buffer, fileLen, 1, file);
fclose(file);
//free(buffer);
char header[102400];
sprintf(header,
"HTTP/1.1 200 OK
"
"Date: Thu, 19 Feb 2009 12:27:04 GMT
"
"Server: Apache/2.2.3
"
"Last-Modified: Wed, 18 Jun 2003 16:05:58 GMT
"
"ETag: "56d-9989200-1132c580"
"
"Content-Type: image/png
"
"Content-Length: %i
"
"Accept-Ranges: bytes
"
"Connection: close
"
"
", fileLen);
char *reply = (char*)malloc(strlen(header)+fileLen);
strcpy(reply, header);
strcat(reply, buffer);
printf("msg %s
", reply);
//return 0;
int sd = socket(PF_INET, SOCK_STREAM, 0);
struct sockaddr_in addr;
bzero(&addr, sizeof(addr));
addr.sin_family = AF_INET;
addr.sin_port = htons(8081);
addr.sin_addr.s_addr = INADDR_ANY;
if(bind(sd,&addr,sizeof(addr))!=0)
{
printf("bind error
");
}
if (listen(sd, 16)!=0)
{
printf("listen error
");
}
for(;;)
{
int size = sizeof(addr);
int client = accept(sd, &addr, &size);
if (client > 0)
{
printf("client connected
");
send(client, reply, strlen(reply), 0);
}
}
但是我的浏览器不理解这个=(我到底做错了什么?
but my browser does not understand this =( What am I doing wrong exactly?
UPD:我尝试发送文本数据 - 没问题.但二进制数据失败
UPD: I tried to send text data - its OK. But binary data fails
推荐答案
问题是您的消息正文被视为以空字符结尾的文本字符串(您使用 strcat
和 strlen
上),当它不是一个时:它是二进制数据(PNG 文件).因此,strcat
和 strlen
都在图像的第一个 0 字节处停止(通常很早).
The problem is that your message body is being treated as a null-terminated text string (you use strcat
and strlen
on it), when it isn't one: it is binary data (a PNG file). Therefore, strcat
and strlen
both stop on the first 0 byte in the image (typically quite early).
您的程序甚至打印出响应正文:请注意它给出了正确的标头,但是一旦 PNG 标头(二进制数据)开始,只有几个字节.
Your program is even printing out the response body: notice that it gives the correct header, but that once the PNG header (binary data) starts, there is only a few bytes.
strcat(reply, buffer)
行,其中buffer
可能包含 0 个字节.改成memcpy(reply+strlen(header), buffer, fileLen)
.send(client, reply, strlen(reply), 0)
行,其中reply
可能包含 0 个字节.预先计算回复的长度,或者将strlen替换为strlen(header)+fileLen
.
- The line
strcat(reply, buffer)
, wherebuffer
potentially contains 0 bytes. Change it tomemcpy(reply+strlen(header), buffer, fileLen)
. - The line
send(client, reply, strlen(reply), 0)
, wherereply
potentially contains 0 bytes. Pre-calculate the length of the reply, or replace the strlen withstrlen(header)+fileLen
.
另一个错误是您在完成后没有关闭连接,因此浏览器将永远等待.你需要这个,在 send
之后:
Another bug is that you aren't closing the connection when you're done, so the browser will just wait forever. You need this, after send
:
close(client);
这篇关于使用 C 套接字在 HTTP 响应中发送二进制文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!