c sendfile第二次不起作用

时间:2012-08-08 07:54:42

标签: c sockets sendfile

这是LIST ftp的cmd的片段:

count = file_list("./", &files);
if((fp_list = fopen("listfiles.txt", "w")) == NULL){
  perror("Impossibile aprire il file per la scrittura LIST");
  onexit(newsockd, sockd, 0, 2);
}
for(i=0; i < count; i++){
  if(strcmp(files[i], "DIR ..") == 0 || strcmp(files[i], "DIR .") == 0) continue;
  else{
    fprintf(fp_list, "%s\n", files[i]);
  }
}
fclose(fp_list);
if((fpl = open("listfiles.txt", O_RDONLY)) < 0){
  perror("open file with open");
  onexit(newsockd, sockd, 0, 2);
  exit(1);
}
if(fstat(fpl, &fileStat) < 0){
  perror("Errore fstat");
  onexit(newsockd, sockd, fpl, 3);
}
fsize = fileStat.st_size;
if(send(newsockd, &fsize, sizeof(fsize), 0) < 0){
  perror("Errore durante l'invio grande file list");
  onexit(newsockd, sockd, fpl, 3);
}
rc_list = sendfile(newsockd, fpl, &offset_list, fileStat.st_size);
if(rc_list == -1){
  perror("Invio file list non riuscito");
  onexit(newsockd, sockd, fpl, 3);
}
if((uint32_t)rc_list != fsize){
  fprintf(stderr, "Error: transfer incomplete: %d di %d bytes inviati\n", rc_list, (int)fileStat.st_size);
  onexit(newsockd, sockd, fpl, 3);
}
printf("OK\n");
close(fpl);
if(remove( "listfiles.txt" ) == -1 ){
  perror("errore cancellazione file");
  onexit(newsockd, sockd, 0, 2);
}

wher &files被声明为char **files,而函数list_files是我编写的与我的问题无关的函数。
我的问题:第一次LIST cmd它被称为正常工作但如果我再次呼叫LIST它总是给我“错误,转移不完整”我不明白为什么......

2 个答案:

答案 0 :(得分:3)

sendfile函数可能无法在一次调用中发送所有数据,在这种情况下,它将返回一个 less 的数字。您将此视为错误,但您应该再试一次。一种方法是使用类似于此的循环:

off_t offset = 0;
for (size_t size_to_send = fsize; size_to_send > 0; )
{
    ssize_t sent = sendfile(newsockd, fpl, &offset, size_to_send);
    if (sent <= 0)
    {
        if (sent != 0)
            perror("sendfile");
        break;
    }

    offset += sent;
    size_to_send -= sent;
}

答案 1 :(得分:2)

我发现了我的问题 当我多次致电sendfile时,变量off_t offset_list;仍然“脏”
如果第一次调用sendfile offest_list将有第二次调用该函数时将不会删除的值。
所以如果我必须写{{1在offset_list = 0;之前完成所有工作!