2011-04-08 161 views
3

我試圖使用套接字發送二進制文件。C:將文件發送到套接字

 FILE *file; 
     char *file_data; 
     file = fopen(filepath, "rb"); 

     //Allocate memory 
     file_data=(char *)malloc(fileLen+1); 

     //Read file contents into buffer 
     fread(file_data, fileLen, 1, file); 
     fclose(file); 

     sent = send(client, file_data, strlen(header)+fileLen, 0); 

它的工作原理確定,但有些文件太大,我想讀的一部分來緩衝,發送,然後讀取第二部分,發送等。

我試圖讓使用FREAD和與fgets部分,但我失敗了=(怎麼做是正確的

UPD:麻煩是閱讀從客戶端傳入的請求,我沒有讀它。如果我做到這一點。 ,沒有什麼不好的事情發生

+1

你需要告訴我們*你怎麼試過,否則很難回答你失敗的原因。它不應該太難... – unwind 2011-04-08 10:57:09

+0

告訴我們你如何用fread和fgets來做它,我們將告訴你如何使它工作。我會認爲你可以直接調用fread,直到它返回一個不同於你的count的值,並且在同一個循環中寫入到socket。 – mdm 2011-04-08 10:58:49

回答

-1

麻煩在於讀取來自客戶端的傳入請求。我沒看過。如果我這樣做,沒有什麼不好的事情發生

6

喜歡的東西:

#define CHUNK_SIZE 512 

char file_data[CHUNK_SIZE]; 
//or 
char *file_data = malloc(CHUNK_SIZE); 

size_t nbytes = 0; 
while ((nbytes = fread(file_data, sizeof(char), CHUNK_SIZE)) > 0) 
{ 
    sent = send(client, file_data, nbytes, 0); 
} 

但你還需要發送塊中的數據,並且不能假定您將在一次調用中發送所有數據。

這樣send()將不得不看起來更像是這樣的:

int offset = 0; 
    while ((sent = send(client, file_data + offset, nbytes, 0)) > 0) { 
      offset += sent; 
      nbytes -= sent; 
    } 

然後,你必須準備發送時處理中斷()調用(在這種情況下,你只需要重複從相同位置發送):

int offset = 0; 
    while ((sent = send(client, file_data + offset, nbytes, 0)) > 0 
      || (sent == -1 && errno == EINTR)) { 
      if (sent > 0) { 
       offset += sent; 
       nbytes -= sent; 
      } 
    } 

在EINTR的(希望不常有)的情況下,發送將在一個循環中重複,並且很可能有機會完成下一次,並返回數據到您的程序

+1

我想你錯過了'fread'中的最後一個參數(文件指針)..... – 2013-01-19 01:03:40

0
// assumes TCP 
#define MTU_SIZE 1500 
unsigned char mtu[MTU_SIZE]; 
int bytes_read; 

// if you need a header specifing file size send it here 

//Read file contents into buffer 
while ((bytes_read = fread(mtu, MTU_SIZE, 1, file)) != EOF) 
    if (send(client, mtu, bytes_read, 0) < bytes_read) 
     do_error(); 

如果您只是發送一個文件,則不需要標題。您只需關閉TCP連接,當你完成發送和客戶端接收的EOF那麼他們就會知道這是EOF ;-)

您可能還會發現這太問題很有啓發:

Why is writing a closed TCP socket worse than reading one?