阅读总是比要求的少读八位字节

Adr*_*ien 6 c sockets tcp

对于家庭作业,我必须创建一个客户端/服务器程序来存储数据。客户端读取文件并通过套接字将其发送到服务器,服务器接收它并存储数据。最终目标是在多个服务器之间实现分片。该程序运行良好,但是当客户端和服务器不在同一台机器上时,读取函数读取的数据总是比我要求的要少

这是我的阅读代码:

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 函数经常读取我要求它读取的数据量?因为即使没有显示警告,这显然会增加发送时间(不要介意时间消息,它显然是关闭的,我会努力解决的)

PSk*_*cik 5

对于recv,而不是read,POSIX 指定了MSG_WAITALL标志,您应该能够使用它来防止不必要的上下文切换到您的线程,而它所做的只是重新请求 would-be-partial 的其余部分read

MSG_WAITALL 在 SOCK_STREAM 套接字上,这请求功能块直到可以返回全部数据量。如果套接字是基于消息的套接字,如果捕获到信号,如果连接终止,如果指定了 MSG_PEEK,或者如果套接字有待处理的错误,该函数可能会返回较小的数据量。