Best practices with polling / selection and recording

Most examples for select()

and poll()

work in a similar way:

int activity = select(FD_SETSIZE, &readfds , NULL , NULL , NULL);
//...
for (i = 0; i < max_clients; i++){
    int sd = client_socket[i];
    if (FD_ISSET(sd , &readfds)){
        int len = read(sd , buffer, 1024);
        if (len == 0){
            // disconnect
        }
        // echo server, send the data back
        send(sd , buffer , len , 0 );
    }
}

      

The problem I see with this code is why do we think / expect this call to send()

not block?

Even if we do not block the socket, then send()

it will not block, but will send some data or even nothing.

I may be wrong, but I think I need to have an array of strings and use writefds

until the data is sent, etc.

Are there any good examples / practices for this?

+3


source to share


1 answer


You are right for fear of send()

being blocked because he might.

The usual solution is to set the socket mode to non-blocking. Then, every time you call send()

, check:

  • not all data was sent; or
  • errno

    to see if it is EGAIN

    or EWOULDBLOCK

    .


If one of these events occurs, the system buffer is full and you will need to store your data somewhere while waiting until the kernel sends some data and frees up space in the system socket buffer.

Now when you add the socket to the array writefds

passed to select()

to ask the system to tell you when the socket becomes writable again. When this socket is returned select()

, try sending data again. If any additional data is queued at the same time, try sending it as well. If you can send all your data, then remove the socket from the array writefds

(or it will be returned on every call select()

).

+3


source







All Articles