对于家庭作业,我必须创建一个客户端/服务器程序来存储数据。客户端读取文件并通过套接字将其发送到服务器,服务器接收它并存储数据。最终目标是在多个服务器之间实现分片。该程序运行良好,但是当客户端和服务器不在同一台机器上时,读取函数读取的数据总是比我要求的要少
这是我的阅读代码:
static inline size_t reliableRead(const int sourceSocket, void* data, const size_t nBytes)
{
size_t dataRead = 0;
unsigned int lossInARaw = 0;
do
{ const size_t readStatus = read(sourceSocket,data+dataRead,nBytes - dataRead);
if (readStatus == (unsigned)-1)
{
LOG_ERRNO_ERROR("error on read");
break;
}
dataRead += readStatus;
if (readStatus != nBytes)
LOG_WARNING("data loss(%u): read %zu/%zuo",++lossInARaw,dataRead,nBytes);
} while (dataRead < nBytes);
return dataRead;
}
Run Code Online (Sandbox Code Playgroud)
这是我尝试读取 1024o 和 8192o 块时的结果。首先客户端和服务器是两个不同的主机,然后在同一个
服务器端从另一台机器上的客户端接收以 1024o 为单位切片的数据时

服务器端从另一台机器上的客户端接收以 8192o 块分割的数据时

从图像上看,read 显然能够读取 1024o 以上。我以前从未进行过套接字编程,所以也许我遗漏了一些东西,我怎样才能让 read 函数经常读取我要求它读取的数据量?因为即使没有显示警告,这显然会增加发送时间(不要介意时间消息,它显然是关闭的,我会努力解决的)
对于recv,而不是read,POSIX 指定了MSG_WAITALL标志,您应该能够使用它来防止不必要的上下文切换到您的线程,而它所做的只是重新请求 would-be-partial 的其余部分read。
MSG_WAITALL 在 SOCK_STREAM 套接字上,这请求功能块直到可以返回全部数据量。如果套接字是基于消息的套接字,如果捕获到信号,如果连接终止,如果指定了 MSG_PEEK,或者如果套接字有待处理的错误,该函数可能会返回较小的数据量。