dontHaveName
dontHaveName

Reputation: 1937

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.

Upvotes: 1

Views: 3103

Answers (2)

dbush
dbush

Reputation: 225087

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

Upvotes: 2

Steffen Ullrich
Steffen Ullrich

Reputation: 123541

A string in C ends with the \0 character. It is likely that the binary representation of your image contains this character somewhere inside the data. This means any use if %s, strlen(..) etc will simply stop at the \0 character and thus cannot be used for binary data.

Upvotes: 2

Related Questions