2

首先让我说这是一项家庭作业,我不是交流程序员。我已经为此工作了几天,但我被困住了。我已经从头到尾阅读了 beej 指南,并且已经在谷歌上搜索了一个星期,是时候寻求帮助了。我有一个客户端-服务器 TCP 套接字应用程序,可以按预期发送和接收消息,现在我需要实现简单的文件上传/下载功能。

下面的代码几乎可以工作,但它在复制文件的开头添加了 4 个字节,两个不可打印字符后跟 \00\00,客户端不再响应。

客户端使用 select 命令通过非阻塞套接字连接。

我知道有很多改进的空间,但有人可以帮助我开始吗?

// 服务器

void put (int sockfd, char *localfile) {

    // Get file Size
    FILE *file;
    int size;

    file = fopen(localfile, "rb");
    fseek(file, 0, SEEK_END);
    size = ftell(file);
    fseek(file, 0, SEEK_SET);

    //Send file Size
    write(sockfd, &size, sizeof(int));

    //Send file as Byte Array
    char send_buffer[size];

    memset(send_buffer, 0, sizeof(send_buffer));
    //while(!feof(file)) {
    //    fread(send_buffer, 1, sizeof(send_buffer), file);
    //    write(sockfd, send_buffer, sizeof(send_buffer));
    //    memset(send_buffer, 0, sizeof(send_buffer));
    //}

    int sent;

    while((sent = fread(send_buffer, sizeof(char), sizeof(send_buffer), file)) > 0)
    {
        if(send(sockfd, send_buffer, sent, 0) < 0)
        {
            fprintf(stderr, "[Server] ERROR: Failed to send file %s. (errno = %d)\n", localfile, errno);
            break;
        }
        memset(send_buffer, 0, sizeof(send_buffer));
    }
    fclose(file);
}

//客户

void get(int sockfd, char *remotefile) {

    FILE *file;
    int size;

    //Read file Size
    read(sockfd, &size, sizeof(int));

    //Read file Byte Array
    char p_array[size];
    memset(&p_array, 0, sizeof(p_array));

    read(sockfd, p_array, size);

    //Convert it Back into file
    file = fopen(remotefile, "wb");
    fwrite(p_array, 1, sizeof(p_array), file);
    fclose(file);
}
4

1 回答 1

3

您在读取套接字时忽略读取计数,并假设每次读取都填满缓冲区,这是常见的错误。你不能这样假设。

你的发送循环不会犯这个错误。因此,将其用作模型,但将其重做接收以便使用read()而不是fread(). 然后您应该看到不需要分配文件大小的缓冲区,因此不需要在文件之前发送文件大小,除非您计划保持连接打开以用于其他目的。

也没有任何memset()电话的理由。

于 2013-03-29T02:54:14.923 回答