2016-01-17 63 views
1

我正在编写一个简单的客户端/服务器应用程序,并遇到了一个非常奇怪的问题。客户端读取其他文件后不读取任何数据

我想发送一个.zip文件到客户端,然后再发送一些数据。 发送.zip工作正常,服务器写入套接字,客户端从套接字读取,正如预期的那样。

之后的问题是 服务器运行正常,并一直写入套接字,但客户端不会读取任何内容。无论我尝试发送什么,它都会停留在接下来的read()调用中。

我检查过套接字描述符是否正常,它们是。我也认为,可能没有足够的数据在客户端读取套接字,但肯定是。

我也试图做同样的读/写之前和发送该.zip文件后:它工作正常之前,但客户没有看到它后发送该.zip文件。 我没有想法。

这是我用来发送的.zip功能:

typedef struct thData{ 
int idThread; //thread ID 
int cl; //client descriptor 
}thData; 

void send_info(struct thData tdL) 
{ 
    char file_path[256]="v1.zip"; 
    char sd_buffer[256]; 
    bzero(sd_buffer, 256); 

    FILE *fd = fopen(file_path, "rb"); 
    if(fd == NULL) 
    { 
     printf("ERROR: %s not found.\n", file_path); 
     exit(1); 
    } 


    int read_size; 
    int write_size; 
    while((read_size = fread(sd_buffer, sizeof(char), 256, fd)) > 0) 
    { 
     if((write_size=write(tdL.cl, sd_buffer, read_size)) < 0) 
     { 
      perror("ERROR: writing to client: \n"); 
      break; 
     } 
     bzero(sd_buffer, 256); 
    } 
} 

我使用接收的.zip什么:

void receive_info(int sd) //sd being the socket descriptor 
{ 
    char* file_path = "subject.zip"; 
    char received_buffer[256]; 

    int total_received=0; 
    int total_wrote=0; 

    FILE *fd = fopen(file_path, "wb"); 
    if(fd == NULL) 
     printf("Cannot open %s\n", file_path); 
    else 
    { 
     bzero(received_buffer, 256); 
     int read_size = 0; 
     while((read_size = read(sd, received_buffer, 256)) > 0) 
     { 
      total_received=total_received+read_size; 

      int write_size = fwrite(received_buffer, sizeof(char), read_size, fd); 
      total_wrote=total_wrote+read_size; 

      if(write_size < read_size) 
      { 
       perror("ERROR: \n"); 
      } 
      bzero(received_buffer, 256); 
      if (read_size == 0 || read_size != 256) 
      { 
       break; 
      } 
     } 
     if(read_size < 0) 
     { 

      perror("ERROR: reading: "); 
      exit(1); 

     } 
     fclose(fd); 
    } 
} 

任何帮助将不胜感激。

回答

1

我认为问题在于你读得太多。

在TCP中,从一个对端发送到另一个对端的报文中没有边界。它只是一个字节流,从recv/read()收到的作品与send/write()发送的作品没有任何关系(原则上)。

现在,假设您的ZIP文件长度为300个字节,并且您的额外数据长度为10个字节。您的发件人代码将执行:

  • 写入256个字节(ZIP的第一部分)。
  • 写入44个字节(ZIP的最后一部分)。
  • 写入10个字节(额外的数据)。

和接收器的代码就可以了:

  • 阅读256,得到256个字节(从ZIP第一块)。
  • 读取256,获取54个字节(ZIP中的最后一部分加上额外的数据)。
  • 读取XXX个字节,永远等待!

如果你仔细看的ZIP文件,你可能会看到这些额外的字节在subject.zip结束。

解决方案如果您不想关闭并打开另一个套接字,则会使协议更复杂一些。例如,您可以在包含文件大小的文件(标题)之前发送结构。这样接收机就会知道什么时候停止阅读。

PS:请注意,您的代码有一些有风险的边缘。例如,write()可能不会写入所有给定的字节,但您没有检查该字节;你是不是关闭文件...

PS2:我觉得奇怪的是,你觉得有必要写sizeof(char),而不是仅仅1但你写256,而不是sizeof(sd_buffer)

+0

谢谢!你对额外的字节是正确的! – user3211838

相关问题