【问题标题】:c sendfile doesn't works the 2nd timec sendfile 第二次不起作用
【发布时间】:2012-08-05 07:13:26
【问题描述】:

这是 LIST ftp 的 cmd 的 sn-p:

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);
}

&amp;files 被声明为 char **files 并且函数 list_files 是我编写的与我的问题无关的函数。
我的问题:第一次LIST cmd 它被称为它可以正常工作,但如果我再次调用 LIST,它总是给我 “错误,传输不完整”我不明白为什么......

【问题讨论】:

  • 从您在问题中发布的代码中是否看到“错误,传输不完整”消息?在那种情况下什么时候?否则,问题中的代码报告什么?
  • 是的,这就是我在问题中发布的内容:) 当 sendfile 函数没有发送所有文件时,它会给我一个错误...
  • 什么是offset_list,你如何初始化它?请记住,如果sendfile 无法发送所有内容,那么它将返回一个小于请求大小的值,您必须调整大小并重试。
  • offset_list 初始化为offset_t...所以我必须这样做吗? send: if((uint32_t)rc_list != fsize){ fprintf(stderr, "Error: transfer incomplete: %d di %d bytes inviati\n", rc_list, (int)fileStat.st_size); goto send; }

标签: c sockets sendfile


【解决方案1】:

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

// Offset into buffer, this is where sendfile starts reading the buffer
off_t offset = 0;

// Loop while there's still some data to send
for (size_t size_to_send = fsize; size_to_send > 0; )
{
    ssize_t sent = sendfile(newsockd, fpl, &offset, size_to_send);

    if (sent <= 0)
    {
        // Error or end of file
        if (sent != 0)
            perror("sendfile");  // Was an error, report it
        break;
    }

    size_to_send -= sent;  // Decrease the length to send by the amount actually sent
}

【讨论】:

  • 哦,谢谢 :) 我已经发布了我的答案,但没有看到你的答案!但是我发现了我的问题,但您的解决方案更好:)
  • 但是如果sent&lt;= 0 我必须退出并关闭套接字...为什么你只休息一下??
  • @polslinux 你可以在你的代码中做任何你想做的事情。 break 只是一个例子。
  • sendfile 不会正确设置偏移量吗?我们需要做offset += sent;
【解决方案2】:

我找到了我的问题。
当我多次调用sendfile 时,变量off_t offset_list; 仍然是“脏”
如果第一次调用 sendfile offest_list 将有一个值不会在我第二次调用该函数时被删除。
所以如果我必须在 @987654325 之前写 offset_list = 0; @ 和所有的工作!

【讨论】:

  • 它也解决了我的问题!!!我整天都沉浸其中!我不能说我现在有多开心。谢谢
猜你喜欢
  • 1970-01-01
  • 2021-01-13
  • 1970-01-01
  • 2014-01-31
  • 2015-06-21
  • 2011-10-04
  • 1970-01-01
  • 2020-04-16
  • 2011-11-10
相关资源
最近更新 更多