Linux BSD sockets blocking issue

I am using BSD TCP sockets under Debian Linux 2.6 and no matter what I do, the socket blocks on recv.

I have set O_NONBLOCK and O_NDELAY using fcntl to no effect.

Any ideas ?

Have you tried select() with timeout set to non-NULL?

Without your code, this amounts to a wild guess.....

The following is my code for both server and client sockets: -

    bzero(&sa,sizeof(struct sockaddr_in)); /* clear our address */ 

    if (master) {

        if (gethostname(myname,MAXHOSTNAME) < 0) std::cerr << "Error hostname: " << myname; /* who are we? */ 
        hp= gethostbyname(myname); /* get our address info */     

        if (hp != NULL)  { 
            sa.sin_family= hp->h_addrtype; /* this is our host address */ 
            sa.sin_port= htons(port); /* this is our port number */ 
        }

        if ((s= socket(AF_INET,SOCK_STREAM,0)) >= 0)  {          /* create socket */  

            int on = 1;
            setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 

            if (bind(s, reinterpret_cast<struct sockaddr*>(&sa), sizeof sa) >= 0)  {    /* bind address to socket */ 

                listen(s, 3); /* max # of queued connects */ 
                established = true;
                master_socket_ref = s;

                int flags = fcntl(master_socket_ref, F_GETFL, 0);
                fcntl(master_socket_ref, F_SETFL, flags | O_NONBLOCK | O_NOCTTY | O_NDELAY | O_RDWR | O_ASYNC); 

            }
            else close(s);
        } 
    }
    else {

        if ((hp= gethostbyname(node_name(node_ref).c_str())) != NULL)  {
  
            bzero(&sa,sizeof(sa)); 
            bcopy(hp->h_addr, (char *)&sa.sin_addr, hp->h_length); /* set address */ 

            sa.sin_family= hp->h_addrtype; 
            sa.sin_port= htons(port); 

            if ((s= socket(hp->h_addrtype,SOCK_STREAM,0)) >= 0)  {   /* get socket */ 

                int on = 1;
                setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 

                if (connect(s, reinterpret_cast<struct sockaddr*>(&sa), sizeof sa) >= 0)  {       /* Connect */
                    established = true;
                    socket_ref = s;

                    int flags = fcntl(socket_ref, F_GETFL, 0);
                    fcntl(socket_ref, F_SETFL, flags | O_NONBLOCK | O_NOCTTY | O_NDELAY | O_RDWR | O_ASYNC); 
                }
                else close(s);   
            }
        }
    }

If I have set up a server listening socket using the above code, I accept a client as follows :-

    getsockname(master_socket_ref, reinterpret_cast<struct sockaddr*>(&isa), reinterpret_cast<socklen_t*>(&i));           /* for accept() */ 

    int on = 1;
    socket_ref = accept(master_socket_ref, reinterpret_cast<struct sockaddr*>(&isa), reinterpret_cast<socklen_t*>(&i));
    setsockopt(socket_ref, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)); 

    int flags = fcntl(socket_ref, F_GETFL, 0);
    fcntl(socket_ref, F_SETFL, flags | O_NONBLOCK | O_NOCTTY | O_NDELAY | O_RDWR | O_ASYNC);

Many thanks Jim, the Select API seems to fix the blocking issue (I used a 100 msec timeout on select()). Although I haven't test the received data path properly yet, but the blocking is not an issue anymore.

For others who are interested, the following may be interesting to you :-

BSD Sockets Tutorial