Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if a non-blocking send succeeded

Tags:

c

io

sockets

I am making one non-blocking send call on one socket and next a blocking receive on another socket. After that I want to check if the non-blocking send succeeded or failed. How can this be done?

    while (i)
    {
      retval = send (out_sd, s_message, strlen (s_message), MSG_DONTWAIT);
      retval = recv (client_sd, r_message, MSG_LEN, 0);
      r_message[retval] = '\0';
      /* Here I want to wait for the non-blocking send to complete */
      strcpy (s_message, r_message);
      strcpy (r_message, "");
      i--;
    }
like image 608
phoxis Avatar asked Dec 12 '12 14:12

phoxis


2 Answers

You are somehow mixing synchronous and asynchronous IO, which is normally a bit confusing, but I don't see any practical problem in here.

To avoid hard polling (which is keeping looking if your operation has finished in a loop) you should use a select() to wait for your channel/socket to become available for more write operations. This would tell you that the previous one was finished (or that it was fully taken in charge by your OS, which is the same).

The select() function is the base for asynchronous IO in C, you should read about it in here, and this is an example I think might be useful to you.

Pay attention though that select() supports read, write and exception events, the example shows a read select, you want to do a write select.

like image 80
Federico Bonelli Avatar answered Sep 26 '22 11:09

Federico Bonelli


send() will return you the number of bytes sent or -1 in case of an error.

If there's enough buffer in the network stack to send at least some bytes from your message, retval will contain the number of bytes sent, which may be less than the number of bytes you wanted to send. If the network stack buffer is full, it will contain -1 and errno will be set to EAGAIN or EWOULDBLOCK.

In all cases, the send call is complete as soon as it returns. So you do not have to wait for the non-blocking send to complete anywhere else, you need to check the return value right away after the send() call returns.

like image 44
Laurent Parenteau Avatar answered Sep 25 '22 11:09

Laurent Parenteau