【问题标题】:File transfer through sockets, final size with less bytes通过套接字传输文件,最终大小用更少的字节
【发布时间】:2010-10-15 15:29:06
【问题描述】:

我试图通过 C 中的套接字接收一些文件。但服务器向我发送了一个 1000000 字节文件的 64 字节数据包,我在目标文件上获得了大约 999902 字节。

while ((n = read(sd, buffer_in, BUFSIZE ))) //  BUFSIZE = 64 
{
    if(n<0)
    {
       printf("Fail.\n");
       fclose(archivo);
       return -1;
    }

    if(fwrite(buffer_in, n, 1, f) !=1 ) 
    { 
       printf("fwrite error.\n");
       fclose(archivo);
       return -1;
    }

    bytes+=n;
}

printf("We received %d bytes",  bytes);

当通过本地 TCP/IP 套接字使用时,它可以工作,但不能用于慢速连接。我通过调试看到我得到了很多 64 字节的块,并且在 EOF 附近有一个 30 字节的块。我知道您可以在 read() 上获得更少的字节,因为当任何数据(> 1 字节)可用时调用返回。但是这个条件不应该被while抓住吗?当 n == 0 时应返回,即不再有数据 (EOF)。

感谢您的帮助。

(编辑)

发送代码如下:

while (n=read(file_fd, buffer, BUFSIZE))
{
   write (sdaccept, buffer, n)
}

我知道 read() 和 write() 都可能返回 N

(编辑二)

用 10673 字节的 C 源测试,接收到 10575 没有损坏,除了目标文件缺少前 98 个字节!!!

【问题讨论】:

  • 大约 999902?或者确切地说?
  • 我发现这段代码没有明显的缺陷 - 请也显示发送代码。
  • 特别奇怪,因为64正好分成1000000
  • 添加了发送代码... Pax:是的,999902 正好来自一个 1 百万字节的文件。
  • 你应该测试while ((n = read(...)) &gt; 0)。目前,即使出现错误,您仍在继续 (n == -1).

标签: c sockets file-transfer


【解决方案1】:

提供的发送代码忽略了这样一个事实,即套接字上的 write() (或 send() )不必写入整个缓冲区。

write()/send() 如果底层子系统拒绝接收更多数据,则可能决定部分写入或根本不写入(例如,网络子系统可能有一个要发送的数据队列,而这个队列已经满的)。这很可能是在连接速度较慢的情况下。

发送端应检查write()的返回值,以检测实际写入了多少数据并进行相应调整。

应该像这样写:

int readAmount;
while( readAmount = read(file_fd, buffer, BUFSIZE) > 0 )
{
    int totalWritten = 0;
    do {
       int actualWritten;
       actualWritten = write (sdaccept, buffer + totalWritten, readAmount - totalWritten);
       if( actualWritten == - 1 ) {
           //some error occured - quit;
       }
       totalWritten += actualWritten;
    } while( totalWritten < readAmount );
}

【讨论】:

  • 发送代码很容易出现我描述的问题。添加了建议的修复。
  • 更具体地说,有1M字节写入但接收较少! :(
  • 你的意思是,你把所有迭代的totalWritten相加,它是1M,但接收方仍然收到不完整的数据?
  • 最后收到的数据大小是 30 字节,好像收据读取后得到 EOF
  • 您应该尝试准确检测丢失的数据。例如,从磁盘读取一个块后,将一个整数写入其前四个字节并递增该整数。在接收端进行检查。
猜你喜欢
  • 2020-02-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
相关资源
最近更新 更多