【问题标题】:C sockets receive fileC套接字接收文件
【发布时间】:2014-05-10 21:22:13
【问题描述】:

我正在开发非常简单的 ftp 客户端。我已经创建了一个数据连接套接字,但是我无法成功传输文件:

FILE *f = fopen("got.png", "w");
int total = 0;
while (1){      
    memset(temp, 0, BUFFSIZE);
    int got = recv(data, temp, sizeof(temp), 0);

    fwrite(temp, 1, BUFFSIZE, f);
    total += got;

    if (total == 1568){
    break;
    }
}
fclose(f);

BUFFSIZE = 1568

我知道我的文件大小为 1568 字节,所以我尝试下载它只是为了测试。当我尝试下载 .xml 或 .html 文件时,一切都是文件,但当我尝试下载 png 或 avi 文件时,没有任何好处。原始文件大小为 1568,但 got.png 文件大小为 1573。我不知道是什么原因造成的。

编辑:

我已经修改了我的代码,所以现在它看起来像(它可以接受任何文件大小):

FILE *f = fopen("got.png", "w");
    while (1){
        char* temp = (char*)malloc(BUFFSIZE);
        int got = recv(data, temp, BUFFSIZE, 0);

        fwrite(temp, 1, got, f);

        if (got == 0){
            break;
        }
    }
    fclose(f);

仍然收到的文件太长了 2 个字节。

【问题讨论】:

  • 听起来像是文本/二进制 I/O 问题。您是否有机会在 Windows 上运行它?
  • 在这种情况下,请尝试为二进制(而不是文本)I/O 打开文件。并确保读者也这样做。
  • 太棒了!我知道这很简单,但你肯定挽救了我的一天。谢谢

标签: c file sockets ftp transfer


【解决方案1】:

您正在以文本模式打开文件,因此在写入文件时,纯 CR/LF 字符将被转换为 CRLF 对。您需要以二进制模式打开文件:

FILE *f = fopen("got.png", "wb");

【讨论】:

    【解决方案2】:

    即使您只收到部分缓冲区,您也总是在写入整个缓冲区。大约 50% 的 TCP 问题都存在同样的问题。

    memset 不是必需的。我希望 temp 是一个数组,这样sizeof(temp) 就不会计算为本机指针大小。最好在那里使用BUFFSIZE


    看到你的编辑,在解决第一个问题后还有另一个问题:以二进制模式打开文件。

    【讨论】:

    • 在这种特定情况下,这似乎不是问题,因为 OP 获得的消息比预期的更大
    • 对我来说非常有意义。他正在编写比预期更大的缓冲区。我们现在实际上知道了他的网络的 MTU :)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-12-16
    • 1970-01-01
    • 2013-04-01
    相关资源
    最近更新 更多