我正在尝试使用套接字发送二进制文件。
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:麻烦在于从客户端读取传入的请求。我没看过。如果我这样做,没有什么不好的事情发生答案 0 :(得分:8)
类似的东西:
#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;
}
然后你必须准备好在send()调用期间处理中断(在这种情况下你只需要从同一个位置重复发送):
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 :(得分:1)
答案 2 :(得分: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; - )
您可能也会发现这个问题很有启发性:
答案 3 :(得分:-2)
麻烦在于从客户端读取传入的请求。我没看过。如果我这样做,没有什么不好的事情发生