Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C/C++ sockets and a non-blocking recv()

Tags:

c++

c

sockets

I'm having a problem where calling recv() system call does not block. I have a client-server structure setup at the moment, and the problem I am having is I send the server one message, while the server is set up so that it's something like:

while (1) {
   char buf[1024];
   recv(fd, buf, sizeof(buf), flags);
   processMsg(buf);
}

It receives the first message correctly, but the recv() does not block and "receives" trash data which is not what is desired. I'd like to react to messages only when they are sent. Can anyone advise?

like image 867
dustin ledezma Avatar asked Jun 13 '11 02:06

dustin ledezma


1 Answers

There's two possibilities: either an error is occurring, or the socket is set to non-blocking mode. To see if an error is occurring, check the return value of recv:

while() {
    char buf[1024];
    int ret = recv(,buf,,)

    if(ret < 0) {
        // handle error
        printf("recv error: %s\n", strerror(errno));
    } else {
        // only use the first ret bytes of buf
        processMsg(buf, ret);
    }
}

To put the socket into non-blocking mode, or to query if a socket is in non-blocking mode, use fcntl(2) with the O_NONBLOCK flag:

// Test if the socket is in non-blocking mode:
if(fcntl(sockfd, F_GETFL) & O_NONBLOCK) {
    // socket is non-blocking
}

// Put the socket in non-blocking mode:
if(fcntl(sockfd, F_SETFL, fcntl(sockfd, F_GETFL) | O_NONBLOCK) < 0) {
    // handle error
}

Note that unless you're explicitly changing the blocking behavior, the socket should be blocking by default, so most likely an error is occurring.

like image 117
Adam Rosenfield Avatar answered Sep 19 '22 09:09

Adam Rosenfield