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
    Please read the forum rules before posting.

    Keep in mind, this is *not* a support forum.
    Our engineers will try to answer your questions between their projects if possible but this can be delayed by longer periods of time.
    Should you be entitled to support you can contact us via our support system: segger.com/ticket/

    Or you can contact us via e-mail.
  • 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