2016-10-31 231 views
1

我正在制作一个简单的http服务器。到目前为止,套接字适用于html文件,现在我正在尝试制作工作映像。c通过套接字发送图像

这是我如何读文件:

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); 

然后,我只是将数据发送到插座:

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(+一个字符 - >一些二进制正方形值为0 0 1 0)。

我在做什么错?

谢谢。

回答

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); 
+0

你能解释一下这个memcpy是如何工作的吗?如果将它们保存为int,它如何复制HTTP标头? – dontHaveName

+0

@dontHaveName'memcpy'函数将指定数量的字节从一个缓冲区复制到另一个缓冲区。缓冲区中的内容无关紧要。在这种情况下,尽管我们使用'snprintf'来构建文本标题。该函数返回了写入的字节数。然后我们使用该值来告诉'memcpy'它应该将多个字节的二进制数据写入缓冲区,即在标题之后。 – dbush

+0

我又遇到了同样的问题。这一次我正在从stidin读取,就像这次我有2个字符变量。我正在读这样的'while((c = getchar())!= EOF){a [index] = c; b [index] = c; index ++)}'。然后我用'write(newsockfd,&a,strlen(b))'直接写入socket。它再次显示GIF89a。为什么?我不在'a'变量上使用任何strlen或printf函数。谢谢(如果你愿意,我可能会创建一个新问题)。 – dontHaveName

2

C中的字符串以\0字符结尾。图像的二进制表示很可能在数据内部的某个位置包含此字符。这意味着任何使用如果%s,strlen(..)等将只停止在\0字符,因此不能用于二进制数据。

+0

嗯,有趣的感谢和解决办法是将fbuffer更改为其他类型? – dontHaveName

+0

@dontHaveName:请参阅http://stackoverflow.com/questions/13656702/sending-and-receiving-strings-over-tcp-socket-separately的方式去。 –

+0

找不到答案,但@dbush已经回答了我。感谢这两个。有用。 – dontHaveName