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];
的位置
问题是,第一种方法全部工作,但使用第二种方法,客户端不接收所有文件,只接收一部分文件。这段代码有什么问题?
谢谢!
答案 0 :(得分: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 */
}
答案 1 :(得分:0)