Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

read always read less octet than asked

Tags:

c

tcp

sockets

For homework, I have to create a client/server program to store data. The client reads a file and sends it to the server via socket, the server receives it and stores the data. The final goal is to implement sharding between several servers. The program works well but the read function always read less data than I asked for when the client and server are not in the same machine

Here is my code for reading:

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;
}

Here is the result when I try to read blocks of 1024o then 8192o. First client and server are two differrents hosts, then on the same

server-side when receiving data sliced in blocks of 1024o from the client on another machine enter image description here

server-side when receiving data sliced in blocks of 8192o from the client on another machine enter image description here

server-side when receiving data when the client is also on the machine enter image description here

From the image, read is clearly capable of reading more than 1024o. I have never socket programming before, so maybe I am missing something, how can I make the read function reads mor often the amount of data I asked it to read ? Because even without displaying the warning, this clearly increases the sending time (don't mind the timing messag, it is clearly off, I will work on that)

like image 924
Adrien Avatar asked Oct 17 '20 17:10

Adrien


1 Answers

For recv, rather than read, POSIX specifies the MSG_WAITALL flag, which you should be able to use to prevent needless context switches to your thread when all it would do is just re-request the remainder of a would-be-partial read.

MSG_WAITALL On SOCK_STREAM sockets this requests that the function block until the full amount of data can be returned. The function may return the smaller amount of data if the socket is a message-based socket, if a signal is caught, if the connection is terminated, if MSG_PEEK was specified, or if an error is pending for the socket.

like image 65
PSkocik Avatar answered Oct 23 '22 04:10

PSkocik