Websockets on non-blocking sockets

This site uses cookies. By continuing to browse this site, you are agreeing to our Cookie Policy.

  • Websockets on non-blocking sockets

    Hi,

    I'm trying to use non-blocking sockets for Websockets, in order to handle multiple websocket connections from a single task. The documentation leads me to believe that this is possible, as blocking calls should return with IP_WEBSOCKET_ERR_AGAIN. Furthermore, I'm using a custom IP-Stack, up to the Socket interface. I am unsure what a socket recv call should return for a non-blocking socket when no data is available. The Socket interface documentation suggests that a value of 1 should be returned when no data is available (sort of a WOULD_BLOCK). How can that be distinguished from actually receiving one byte of data?
    Thank you for your help.
  • Dear glaukos,

    Let me start with a very short explanation on how non-blocking sockets work, although this should be generic to all network stacks that offer some kind of BSD socket interface API.
    Sockets follow a basic principle of three return values only:
    • > 0: Number of bytes processed.
    • = 0: Connection closed or no error in calls that make no sense to return a number of bytes such as bind().
    • < 0: Error. More details about this error state can be retrieved using getsockopt(hSock, 0, SO_ERROR, &SoError, &SoErrorSize) .
    In case of non-blocking sockets these three states are kept as they are. However now the error information requested with getsockopt() can also return WOULD_BLOCK in case
    there were simply no new data for example for a recv() call. This WOULD_BLOCK is not to be mistaken with the WebSocket error code IP_WEBSOCKET_ERR_AGAIN .

    The samples as included within your shipment are designed for blocking sockets but already come somewhat prepared for non-blocking sockets as well.
    In case of using non-blocking sockets there are two ways to handle the WOULD_BLOCK case. Both have one thing in common, error codes from the send/recv callbacks are
    passed through to the application as they are:
    1. In the samples there are some _Panic() calls that will be used when an error other than IP_WEBSOCKET_ERR_AGAIN is returned (errors are negative 1, not positive 1 as
      in your assumption above). So you should add handling for WOULD_BLOCK to all places that will call _Panic() .
    2. Easier way: Evaluate WOULD_BLOCK in the recv() callback and return IP_WEBSOCKET_ERR_AGAIN directly from the callback. This way the sample should be working as is.
    Best regards,
    Oliver
  • Hi Oliver,

    thank you for your quick reply.
    I did not check if recv actually returned 1 if no data was available but was just going by the documentation. My IP stack unfortunately does not offer getsockopt with SO_ERROR, so this option is off the table. However, using the callback to return IP_WEBSOCKET_ERR_AGAIN in the case of WOULD_BLOCK worked very well. Thanks again for your help.


    Kind regards

    glaukos