我正在尝试在http响应中发送二进制文件(png图像)。
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\n"
"Date: Thu, 19 Feb 2009 12:27:04 GMT\n"
"Server: Apache/2.2.3\n"
"Last-Modified: Wed, 18 Jun 2003 16:05:58 GMT\n"
"ETag: \"56d-9989200-1132c580\"\n"
"Content-Type: image/png\n"
"Content-Length: %i\n"
"Accept-Ranges: bytes\n"
"Connection: close\n"
"\n", fileLen);
char *reply = (char*)malloc(strlen(header)+fileLen);
strcpy(reply, header);
strcat(reply, buffer);
printf("msg %s\n", 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\n");
}
if (listen(sd, 16)!=0)
{
printf("listen error\n");
}
for(;;)
{
int size = sizeof(addr);
int client = accept(sd, &addr, &size);
if (client > 0)
{
printf("client connected\n");
send(client, reply, strlen(reply), 0);
}
}
但是我的浏览器不理解这个=(我到底做错了什么?
UPD:我试图发送文本数据 - 没关系。但二进制数据失败
答案 0 :(得分:8)
问题是你的邮件正文被视为一个以空字符结尾的文本字符串(你使用strcat
和strlen
),当它不是一个时:它是二进制数据(一个PNG文件)。因此,strcat
和strlen
都停在图像的前0个字节上(通常很早)。
您的程序甚至打印出响应正文:注意它提供了正确的标题,但是一旦PNG标题(二进制数据)启动,只有几个字节。
strcat(reply, buffer)
,其中buffer
可能包含0个字节。将其更改为memcpy(reply+strlen(header), buffer, fileLen)
。send(client, reply, strlen(reply), 0)
,其中reply
可能包含0个字节。预先计算回复的长度,或用strlen(header)+fileLen
替换strlen。另一个错误是,当你完成后你没有关闭连接,所以浏览器将永远等待。在send
之后你需要这个:
close(client);
答案 1 :(得分:1)
HTTP协议指定它需要“\ r \ n”而不是“\ n”。试试吧。 :)
答案 2 :(得分:0)
strcat(reply, buffer); // this is incorrect, because png(buffer) may contain zero byte
send(client, reply, strlen(reply), 0);
strlen(reply) // this is incorrect, because png may contain zero byte
答案 3 :(得分:0)
我试着按照你的所作所为,但无法让它发挥作用。相反,我发现分开发送标题和文件更容易。
e.g。
send(client, header, strlen(header), 0);
send(client, buffer, fileLen + 1, 0);