C-Unix Sockets - Non-Blocking Read

I am trying to create a simple client-server chat program. On the client side, I unscrew another thread to read any incoming data from the server. The problem is that I want to gracefully complete this second thread when a person exits the main thread. I tried to use the general variable "running" to complete, the problem is that the socket read () command is a lock command, so if I execute while (running == 1), the server must send something before it is read read and the while condition can be checked again. I am looking for a method (only for common unix sockets) to do non-blocking reading, some form of peek () would basically work, as I can constantly check the loop to make sure I am done.

The read stream loop is lower, right now it does not have any mutex for common variables, but I plan to add that don't worry later!;)

void *serverlisten(void *vargp) { while(running == 1) { read(socket, readbuffer, sizeof(readbuffer)); printf("CLIENT RECIEVED: %s\n", readbuffer); } pthread_exit(NULL); } 
+4
source share
5 answers

You can make the socket non-blocking, as suggested in another post, plus use select to wait for input with a timeout, for example:

 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 
+8
source
 fcntl(socket, F_SETFL, O_NONBLOCK); 

or if you have other flags:

 int x; x=fcntl(socket ,F_GETFL, 0); fcntl(socket, F_SETFL, x | O_NONBLOCK); 

then check the read return value to see if data is available.

Note: a bit in a search engine will give you a ton of examples.

You can also use blocking sockets and peek with select with a timeout. It seems more appropriate here, so you are not making the wait.

+6
source

It’s best to get rid of the extra thread and use select() or poll() to process all in one thread.

If you want to save a stream, one thing you can do is call shutdown() on the socket with SHUT_RDWR , which will disconnect the connection, wake up all threads blocked on it, but save the file descriptor. After you have joined the read stream, you can close the socket. Note that this only works on sockets and not on other types of file descriptors.

+2
source

Look for the setsockopt function with the SO_RCVTIMEO option.

+1
source

It may not be the specific answer you are looking for, but it may be a place where you can find it. I'm reading now:

Unix Network Programming, Volume 1: Sockets Network Interface, 3rd Edition

And there are many examples of multithreaded, non-blocking servers and clients. In addition, they explain a lot of reasoning and trade-offs that go between different methods.

Hope this helps ...

0
source

Source: https://habr.com/ru/post/1380946/


All Articles