文件部分以c发送

时间:2013-12-16 12:01:38

标签: c linux windows file-upload tcp

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

我用来发送数据的缓冲区的大小是65535.当文件大小超过这个值时,我收到一个错误,说“通过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);
    }

我做错了什么?

2 个答案:

答案 0 :(得分:0)

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

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

另外,您要检查512而不是LENGTH。但只有0才意味着你已经完成了(假设你的连接不是NONBLOCKED。)

作为旁注:您不必在使用它们之前清除缓冲区(bzero,memset),因为read / recv会覆盖缓冲区的内容。

答案 1 :(得分:0)

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

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

fr_block_sz可以是165535之间的任何内容 - 您发送的大小块。

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