2011-04-08 142 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?