I have a client server client connection where the server reads the message sent by the client every 1 second but I do not want the server to keep on waiting for a message for too long. I tried using the select() function but the server continues waiting for some message to read. Could anyone tell me what I am doing wrong please?
fd_set master; fd_set read_fds; FD_ZERO(&master); FD_ZERO(&read_fds); FD_SET(sock, &master); while (1) { bzero(message, 256); sleep(1); read_fds = master; if(select(sock+2, &read_fds, NULL, NULL, NULL) < 0) error("ERROR reading"); //if there is any data to read from the socket else if(FD_ISSET(sock, &read_fds)){ n = read(sock, buffer, 256); c = buffer[0]; printf("1st char is %c",c); }//close else if statement else printf("Nothing was read"); }//close while loop
Advertisement
Answer
A few comments that are too long to fit in the comments…
The first parameter to select
really only needs to be sock+1
.
By passing NULL
for the timeout, select
will block indefinitely (so you might as well have just called read
).
When select
does tell you that sock
is ready for reading, there may only be one byte present, even if the other end wrote more then that. You will have to loop, reading the socket until you get the number of bytes you want. You will have to decide if you want the timeout only while waiting for the first byte, or if you want to timeout in the middle (I.e. is the select
inside or outside the loop).
Normally, when using select
, you only want to block in select
, and not in read
, so the socket should be put in non-blocking mode, and you should be prepared for the read
to fail with EWOULDBLOCK
.
If you do time out, do you want to close the connection? If you got half way through a message, you can’t just throw away the half and keep going because you would now be expecting the next byte to be another start of message when it will now be a middle.