2011-11-17 44 views
0

對於如何將文件從http服務器發送到客戶端(網絡瀏覽器),我有點困惑。如何通過C中的網絡發送段中的二進制文件?

首先我發送標題,我的下一個任務是發送文件內容。不過,我想一次性發送512字節的數據段而不是整個文件,因爲我遇到了一些問題。

我有點失落如何實現這一點。這是我想要的

read file1; 
while (seg=get_next_segment(file1)){ 
    do 
    send(seg) 
    until (seg_is_sent) 
} 

但是,我似乎無法找到適當的功能來實現這一目標。 freadfseek穿過我的腦海,但第一個一次讀取整個文件和fseek我沒有看到一種方法來從文件中抓取一部分(而不是從文件指針直到文件尾部讀取) 。

+1

如果'fread'讀取整個文件一次,它爲什麼參數告訴它多少看?而'fseek'完全不能用於閱讀。 –

+0

我可以問你爲什麼要分段發送?另外,'sendfile'效率更高。 –

+0

@yi_H原因是我之前把它作爲一個整體發送過來,它並沒有作爲一個整體到達。我在瀏覽器中收到一條消息,如「無法讀取文件」 – Pithikos

回答

3

fread不會將整個文件讀到最後。它確切地讀取您告訴它讀的多少。

size_t 
fread(void *restrict ptr, size_t size, size_t nitems, 
    FILE *restrict stream); 

size_t 
fwrite(const void *restrict ptr, size_t size, size_t nitems, 
    FILE *restrict stream); 

這兩個函數的大小和nitems。您可以將大小設置爲512,將項目數量設置爲1(反之亦然),並只讀取文件的該部分。

+0

現在我明白了。然而我很好奇爲什麼這個函數是以這種方式實現的,而不是直接給出'讀取的字節數'。 – Pithikos

+0

一個非常常見的使用模式是'fread(foo,sizeof(some_complex_datastructure_t),x,fp);'。我不確定是否有一個合理的技術原因,除了你在談論分立元素而不是字節。 – Gian

2

從手冊頁:

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream);

功能fread()讀取nmemb個數據的元素,每個大小字節長,從流指向由,將它們存儲在由ptr給出的位置處。

正如你所看到的,你不必與fread讀取整個文件,你可以在nmemb個大小的塊讀取它。

如果您使用C語言編寫自己的Web服務器,您可能需要查看libmicrohttpd,它是C中的Web服務器,用於嵌入到其他應用程序中,它可以爲您處理流式傳輸文件。

1

我感到有點......怎麼樣這樣的事情:

for (;;) 
{ 
    char buffer[512]; 
    size_t nread = fread(buffer, sizeof(char), 512, fp); 
    if (nread > 0) 
     send_to_socket(buffer, nread); 

    if (nread < 512) 
    { 
     if (feof(fp)) 
      printf("End of file\n"); 
     if (ferror(fp)) 
      printf("Error reading\n"); 
     break; 
    } 
}