【问题标题】:File transfer from client to server从客户端到服务器的文件传输
【发布时间】:2016-12-27 15:29:59
【问题描述】:

我正在尝试将文件从客户端发送到服务器。它有时有效,有时无效。第一次尝试发送文件时,它会发送损坏的文件,并且在服务器端形成的文件端是其大小的两倍。但第一次尝试后所有尝试的文件成功传输。谁能帮我解决这个问题?

客户端.c

     message msg;
        msg.type = SEND_FILE;
        char *username, *filename;

        username = strtok(input+6, " ");
        filename = strtok(NULL, "");

        //Get Picture Size
        printf("Getting Picture Size\n");
        FILE *picture;
        picture = fopen(filename, "r");
        int size;
        fseek(picture, 0, SEEK_END);
        size = ftell(picture);
        fseek(picture, 0, SEEK_SET);

        //Send Picture Size
        printf("Getting Picture Size\n");
        sprintf(msg.data, "%d", size);
        strncpy(msg.username, username, 20);

        if(send(connection->socket, &msg, sizeof(message), 0) < 0)
        {
            perror("Send failed");
            exit(1);
        }
        //Send Picture as Byte Array
        printf("Sending Picture as Byte Array\n");
        char send_buffer[size+1];
        fread(send_buffer, 1, sizeof(send_buffer), picture);
        write(connection->socket, send_buffer, sizeof(send_buffer));
        bzero(send_buffer, sizeof(send_buffer));

服务器.c

  //Read Picture Size
printf("Reading Picture Size\n");
int size = atoi(message_text);

//Read Picture Byte Array
printf("Reading Picture Byte Array\n");
char p_array[size];
printf("Converting Byte Array to Picture %d\n", size);
FILE *image;
image = fopen("c4.png", "w");
int readSize = 0;
while (readSize < size) {
  readSize = readSize + read(clients[sender].socket, p_array, size);
  fwrite(p_array, 1, sizeof(p_array), image);
}

fclose(image);

【问题讨论】:

  • 发布完整的函数和结构定义,或者更好的完整程序来显示问题。

标签: c sockets client-server file-transfer


【解决方案1】:

对于初学者:

您不想在每个 fwrite() 上存储相同数量的字节

fwrite(p_array, 1, sizeof(p_array), image);

但只有实际读取的字节数。

sizeof(p_array) 返回p_array 的大小,即size 乘以char 的大小。后者定义为1


除此之外,对read() 的调用完全缺乏错误检查,以及测试对方是否关闭连接。这并不领先。


要解决此问题,您可以这样做:

#include <errno.h> /* for errno */

...

  size_t size = atoi(message_text);
  printf("Reading Picture Byte Array\n");
  char p_array[size];
  size_t readSize = 0;
  while (readSize < size) {
    ssize_t result = read(clients[sender].socket, p_array, size); /* Mind the ssize_t, it's *not* size_t! */
    if (0 >= result)
    {
      if (0 == result)
      {
        fprintf(stderr, "The other end gracefully shut down the connection.\n");

        break;
      }
      else
      {
        if (EINTR == errno)  /* got interrupted, start over */
        {
           continue;
        }

        if (EAGAIN == errno)  /* in case reading from a non-blocking socket: no data available, start over */
        {
           continue;
        }

        /* Something went wrong unrecoverable. */
        perror("read() failed");

        break;
      }
    }
    else
    {
       fwrite(p_array, 1, result, image); 
       /* Also add error checking here! */
       readSize += result;
    }
 }

【讨论】:

  • @alk 谢谢,为我工作。你能告诉我,我可以用这个传输多少文件?
  • @chqrlie:我经常输入errno = EAGAIN... :} 并决定不再搜索此类错误!
  • @MukeshGupta:直到你的磁盘爆炸,或者你饿死等待传输完成...... ;-) 所以不要忘记在此处添加错误检查:fwrite(p_array, 1, result, image);
  • @alk: 是的,谁没有...但是-Wall -Werror 或类似的方法是更好地解决这个愚蠢的错误和许多其他错误。
  • @chqrlie:我很久以前就适应了这种风格,在编译器变得那么聪明之前...... ;-)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多