我正在制作一个简单的http服务器。到目前为止套接字适用于html文件,现在我正在尝试制作工作图像。
这是我阅读文件的方式:
char * fbuffer = 0;
long length;
FILE *f;
if ((f = fopen(file, "r")) == NULL)
{
perror("Error opening file");
exit(1);
}
fseek (f, 0, SEEK_END);
length = ftell(f);
fseek (f, 0, SEEK_SET);
fbuffer = malloc(length);
int total = 0;
if (fbuffer)
{
while (total != length)
{
total += fread(fbuffer, 1, length, f);
}
}
fclose (f);
然后我只是将数据发送到socket:
char response[20048];
snprintf(response, sizeof(response), "HTTP/1.1 200 OK\nContent-Type: %s\nContent-Length: %i\n\n%s", type, (int) strlen(fbuffer), fbuffer);
n = send(newsockfd, response, strlen(response)+1, 0);
为什么它不能用于图像?浏览器显示错误The image “http://127.0.0.1:1050/image.gif” cannot be displayed because it contains errors.
Http响应为:
Content-Length: 7
Content-Type: image/gif
图像有247个字节。在变量长度和总数是值247.变量fbuffer包含GIF89a(+一个char - >一些二进制正方形,值为0 0 1 0)。
我做错了什么?
感谢。
答案 0 :(得分:2)
C中的字符串以\0
字符结尾。图像的二进制表示可能在数据内部的某处包含此字符。这意味着,%s
,strlen(..)
等只会停留在\0
字符处,因此不能用于二进制数据。
答案 1 :(得分:1)
这里的问题是fbuffer
包含二进制数据,但您尝试通过使用strlen
等函数并使用%s
格式说明符打印它来作为字符串处理。
由于二进制数据可能包含空字节,因此这会阻止字符串函数处理它们,因为它们使用空字节来标记字符串的结尾。
您应该使用memcpy
之类的函数将数据放入输出缓冲区。
char response[20048];
int hlen;
hlen = snprintf(response, sizeof(response),
"HTTP/1.1 200 OK\nContent-Type: %s\nContent-Length: %d\n\n", type, length);
memcpy(response + hlen, fbuffer, length);
n = send(newsockfd, response, hlen + length, 0);