Why FD_ISSET returns true after select ()

I am new to socket programming and I am trying to fully understand how this works, but so far I am really stuck on select() .

The problem is that in my code, after selecting it detects activity and set fd, it seems that at the next iterations FD_ISSET will automatically return true, for example, it will ignore the select function. The problem seems to be identical to this, but I did everything I found there, but to no avail: http://compgroups.net/comp.unix.programmer/how-does-fd_isset-return-0-after-returne/55058

I definitely reinitialized the timeval variable after select() , since I am on Linux, and I realized that this function behaves differently on different operating systems. I also reinitialized the fd set with FD_ZERO and FD_SET before selecting.

What am I doing wrong? Here is the code:

 #include <stdio.h> #include <strings.h> #include <sys/select.h> #include <sys/time.h> int main () { struct timeval tv; tv.tv_sec = 5; // 5 seconds timeout tv.tv_usec = 0; fd_set afds, rfds; FD_ZERO(&afds); FD_SET(0, &afds); while (1) { rfds = afds; select(1, &rfds, NULL, NULL, &tv); // linux, reinitialize tv? tv.tv_sec = 5; tv.tv_usec = 0; // so at this point after select runs the first time and detects STDIN activity // it will enter an infinite loop printing "fd 0 is set" (why?) if (FD_ISSET(0, &rfds)) { printf("fd 0 is set\n"); FD_CLR(0, &rfds); } else { printf("fd 0 is NOT set\n"); } } } 

Editing the question, as I am a new user and cannot answer this question:

In fact, I initialize rfds before the choice, when it is assigned the value afds, which, in turn, is always set with FD_ZERO (& afds); FD_SET (0, & amps; afds); This still does not work for me.

Here is what I understand:

  • I add a stdin file descriptor to afds

  • Enter an infinite loop, rfds = afds (rfds will always be = afds at the beginning of the loop)

  • Also, at this time, FD_ISSET (0, & rfds) will always be equal! = 0

  • select has a timeout of 5 seconds, so at this time, if I do not type anything before going 5 seconds, it exits, UNSETTING FD_ISSET (0, & rfds) - is that right? so select will actually disable fd 0 if nothing is typed. This seems to be normal.

  • The problem arises when I print something before the timeout. At this point, FD_ISSET (0, & rfds) returns! = 0, it prints fd 0, and then each cycle fd will be set

Well, that's for sure, I got it right? So in practice, the choice does not wait for time to go through, because it actually detects that fd is ready and exits by setting fd! = 0?

What would you ask another question: if I need the server to automatically send messages to several clients each time (regardless of what it reads from clients), can this be done using select and gettimeofday adapting the code above?

Thanks for the help.

+4
source share
2 answers

select() fires by level, not by edge. When you give him a set of file descriptors, he will return, telling you which ones are readable / writable / exclusive at the moment, and not just those that have recently changed state.

In this case, FD will be marked as readable every time you call select() , because you do nothing to make it unreadable (for example, draining available input) when it appears.

+11
source

The values ​​stored in your fd_set are saved after the select () function fires. In the application, you can select () to monitor many sockets. Automatically clearing fd_set means that you can never find that multiple sockets need maintenance.

You need to execute FD_ZERO () and FD_SET () inside an infinite loop so that on each pass, fd_set is initialized cleanly before calling select ().

+4
source

All Articles