dontHaveName dontHaveName - 1 month ago 6
C Question

c sending image through socket

I'm making a simple http server. So far socket works for html files, now I'm trying to make work images.

This is how I read files:

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


Then I just send data to 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);


Why it doesn't work for images? Browser is showing an error
The image “http://127.0.0.1:1050/image.gif” cannot be displayed because it contains errors.
Http response is:

Content-Length: 7
Content-Type: image/gif


The image has 247 bytes. In variables length and total are values 247. Variable fbuffer contains GIF89a(+one char -> some binary square with values 0 0 1 0).

What am I doing wrong?

Thanks.

Answer

The issue here is that fbuffer contains binary data, but you're attempting to treat is as a string by using functions like strlen and using the %s format specifier to print it.

Since binary data may contain a null byte, this prevents string functions from working on them since they use a null byte to mark the end of a string.

You should instead use functions like memcpy to put data into your output buffer.

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