客户端读取另一个文件后没有读取任何数据

Client does not read any data after reading another file

我正在编写一个简单的 client/server 应用程序,但我 运行 遇到了一个非常奇怪的问题。

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

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

我检查了套接字描述符是否正常,确实如此。我也想过可能是socket里面的数据不够client读取,但是肯定是有的。

我也尝试在发送该 .zip 文件之前和之后做同样的事情 write/read:它在 之前 工作正常,但客户端看不到它 after 发送那个 .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); 
    }
}

如有任何帮助,我们将不胜感激。

我觉得问题是你看书太多了

在 TCP 中,从一个点发送到另一个点的数据包没有边界。它只是一个字节流,从 recv/read() 收到的片段与从 send/write().

发送的片段没有关系(原则上)

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

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

您的接收器代码将执行:

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

如果您仔细查看 ZIP 文件,您可能会在 subject.zip.

末尾看到那些额外的字节

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

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

PS2:我很好奇你觉得有必要写 sizeof(char) 而不是 1 但你写 256 而不是 sizeof(sd_buffer) .