Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C- Unix Sockets - Non-blocking read

I am trying to make a simple client-server chat program. On the client side I spin off another thread to read any incomming data from the server. The problem is, I want to gracefully terminate that second thread when a person logs out from the main thread. I was trying to use a shared variable 'running' to terminate, problem is, the socket read() command is a blocking command, so if I do while(running == 1), the server has to send something before the read returns and the while condition can be checked again. I am looking for a method (with common unix sockets only) to do a non-blocking read, basically some form of peek() would work, for I can continually check the loop to see if I'm done.

The reading thread loop is below, right now it does not have any mutex's for the shared variables, but I plan to add that later don't worry! ;)

void *serverlisten(void *vargp)
{
    while(running == 1)
    {
        read(socket, readbuffer, sizeof(readbuffer));
        printf("CLIENT RECIEVED: %s\n", readbuffer);
    }
    pthread_exit(NULL);
}
like image 454
will Avatar asked Nov 12 '11 20:11

will


People also ask

Is read on socket blocking C?

read() is not blocking in socket programming.

Are UNIX sockets blocking?

The traditional UNIX system calls are blocking. For example: accept() blocks the caller until a connection is present. If no messages space is available at the socket to hold the message to be transmitted, then send() normally blocks.

How would I put my socket in non-blocking mode?

A blocking accept() call does not return to your program until a client connects to your socket program. Change a socket to nonblocking mode using the ioctl() call that specifies command FIONBIO and a fullword (four byte) argument with a nonzero binary value.

Is socket listen blocking?

listen() is non-blocking. accept() blocks and returns a client<>server socket upon connection. what does listen do then ?


1 Answers

You can make socket not blockable, as suggested in another post plus use select to wait input with timeout, like this:

fd_set         input;
FD_ZERO(&input);
FD_SET(sd, &input);
struct timeval timeout;
timeout.tv_sec  = sec;
timeout.tv_usec = msec * 1000;
int n = select(sd + 1, &input, NULL, NULL, &timeout);
if (n == -1) {
    //something wrong
} else if (n == 0)
    continue;//timeout
if (!FD_ISSET(sd, &input))
   ;//again something wrong
//here we can call not blockable read
like image 154
fghj Avatar answered Oct 17 '22 02:10

fghj