0

1:服务器将文件大小复制到缓冲区并发送:

  snprintf(t_buf, 255, "%" PRIu32, fsize);
  if(send(f_sockd, t_buf, sizeof(t_buf), 0) < 0){
    perror("error on sending file size\n");
    onexit(f_sockd, m_sockd, 0, 2);
  }

2:客户端收到文件大小,放入fsize:

  if(recv(f_sockd, t_buf, sizeof(t_buf), 0) < 0){
    perror("error on receiving file size");
    onexit(f_sockd, 0 ,0 ,1);
  }
  fsize = atoi(t_buf);

----------------- 上面的代码让我的程序完美运行!

如果我编写此代码而不是以前的代码,则会出现问题:
1:服务器发送 fsize:

  if(send(f_sockd, &fsize, sizeof(fsize), 0) < 0){
    perror("error on sending file size\n");
    onexit(f_sockd, m_sockd, 0, 2);
  }

2:客户端收到fsize:

  if(recv(f_sockd, &fsize, sizeof(fsize), 0) < 0){
    perror("error on receiving file size");
    onexit(f_sockd, 0, 0, 1);
  }

哪里uint32_t fsize;char t_buf[256];
问题是第一种方法都可以工作,但第二种方法客户端不会收到所有文件,而只会收到其中的一部分。这段代码有什么问题?
谢谢!

4

2 回答 2

1

recv(2)不一定会填充完整的输出缓冲区 - 它可能会返回更少的字节,具体取决于可用的数据量:

接收调用通常会返回任何可用的数据,直到请求的数量,而不是等待接收请求的全部数量。

返回值(当 > 0 时)将是接收到的字节数,因此如果您想确保接收到所有内容,可以在循环中调用它。

或者,您可以传递MSG_WAITALL标志:

此标志请求操作阻塞,直到满足完整请求。但是,如果捕获到信号、发生错误或断开连接,或者要接收的下一个数据与返回的类型不同,则调用返回的数据仍可能少于请求的数据。

因此,在您的情况下,您可以执行以下操作:

ssize_t bytes = recv(f_sockd, &fsize, sizeof(fsize), MSG_WAITALL);

if(bytes == sizeof(fsize))
{
    /* received everything */
}
else
{
    /* something went wrong */
}
于 2012-08-29T10:35:38.313 回答
0

没有更多数据很难说。

可能是字节顺序。您应该打印出 的值fsize

recv()正如评论中提到的,也可能是从 的部分返回。

于 2012-08-29T10:34:09.370 回答