2016-10-31 237 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