【问题标题】:File partially sent in c在 c 中部分发送的文件
【发布时间】:2014-01-03 19:36:30
【问题描述】:

我正在尝试使用 TCP 从 Windows 客户端向 C 语言的 Linux 服务器发送文件。

我用来发送数据的缓冲区大小是 65535。当文件大小超过这个值时,我得到一个错误说'connection reset by peer'或错误代码 10054。当文件大小小于 65535 字节,服务器只接收其中的一部分(通常为 2760 字节)。

我只想发送最大为 50 MB 的文件。

这是我用来发送数据的windows客户端部分:

    char *fileName;     // pointer to filename
    char buf[65535];        // buffer
    int fileSize;   // # bytes to send

    for(i = 0; i < ARRAYSIZE; i++) {
        if(selectList[i] != NULL) {
            // select file
            fileName= selectList[i];                        // get path and filename from selectList
            printf("=============================================\nSending: %s\n", fileName);
            filefd = fopen(fileName, "rb");                 // open file
            if(filefd == NULL) {
                printf("File %s not found\n", fileName);
                exit(1);
            }

            // read and send file
            memset(buf, '\0', 65535);
            while((fileSize= fread(buf, sizeof(char), 65535, filefd)) > 0) {          // read file
                if((numberOfBytes = send(sockfd, buf, fileSize, 0)) < 0) {                                // send buffer
                    printf("send: %s (Error: %d)\n", filename, WSAGetLastError());
                    break;
                }
                printf("#bytes = %i \n", numberOfBytes);
                memset(buf, '\0', 65535);
            }
            printf("File %s send!\n", filename);

            // close file after sending it
            if(fclose(filefd) < 0) {
                printf("fclose: %i", WSAGetLastError());
            }
        } else if(selectList[0] == NULL) {
            printf("no files selected");
        }
    }

selectList包含多个字符串如:C:\Windows\test.txt

Linux 服务器的接收部分:

    char* fr_name = "/home/MtFS/UploadedFiles/public/testFile.gif";
    FILE *fr = fopen(fr_name, "wb");

    if(fr == NULL)
        printf("[Open_File]file %s cannot be created\n", fr_name);
    else {
        bzero(revbuf, LENGTH);
        int fr_block_sz = 0;

        while((fr_block_sz = recv(nsockfd, revbuf, LENGTH, 0)) > 0) {
            int write_sz = fwrite(revbuf, sizeof(char), fr_block_sz, fr);
            if(write_sz < fr_block_sz) {
                error("[Write] error\n");
            }
            bzero(revbuf, LENGTH);
            if (fr_block_sz == 0 || fr_block_sz != 512) {
                break;
            }
        }

        if(fr_block_sz < 0) {
            if (errno == EAGAIN) {
                printf("[Receive] time out\n");
            }
            else {
                printf("[Receive] error\n");
                exit(1);
            }
        }

        printf("[Receive] succesfull\n");
        fclose(fr);
    }

我做错了什么?

【问题讨论】:

    标签: c linux windows file-upload tcp


    【解决方案1】:

    你的问题是那 3 行代码。这不是知道你已经完成的正确方法:

            if (fr_block_sz == 0 || fr_block_sz != 512) {
                break;
            }
    

    您还检查 512 而不是 LENGTH。但只有 0 表示您已完成(假设您的连接不是非阻塞的。)

    附带说明:您不必在使用它们进行读取之前清除缓冲区(bzero、memset),因为读取/接收无论如何都会覆盖缓冲区的内容。

    【讨论】:

    • 感谢您的回复,我已将 if 语句更改为 if (fr_block_sz == 0) 接收文件的大小正确,但文件本身为空/损坏。有什么线索吗?
    • 谢谢它现在有效,我不小心改变了其他东西。如果 (fr_block_sz == 0) 有效。
    • 用-1 检测到错误,read/recv 将返回-1 并设置errno 变量。有关详细信息,请在 Linux 控制台中尝试 man 2 readman 2 recv
    【解决方案2】:

    我认为罪魁祸首是您服务器中的这一行

    if (fr_block_sz == 0 || fr_block_sz != 512) {
    

    fr_block_sz cab 介于 165535 - 您发送的大小块之间。

    在您的代码中,当它不是 512 时,您的服务器正在终止连接。

    【讨论】:

    • 感谢您的回复,我已将 if 语句更改为 if (fr_block_sz == 0) 接收文件的大小正确,但文件本身为空/损坏。有什么线索吗?
    猜你喜欢
    • 2020-10-26
    • 2011-10-21
    • 1970-01-01
    • 2014-05-19
    • 1970-01-01
    • 2019-11-14
    • 2013-07-30
    • 2012-07-12
    • 1970-01-01
    相关资源
    最近更新 更多