<< Prev | Beej's Guide to Network Programming | Next >> |
Check if sockets descriptors are ready to read/write
#include <sys/select.h> int select(int n, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, struct timeval *timeout); FD_SET(int fd, fd_set *set); FD_CLR(int fd, fd_set *set); FD_ISSET(int fd, fd_set *set); FD_ZERO(fd_set *set);
The select() function gives you a way to simultaneously check multiple sockets to see if they have data waiting to be recv()d, or if you can send() data to them without blocking, or if some exception has occurred.
You populate your sets of socket descriptors using the macros, like FD_SET(), above. Once you have the set, you pass it into the function as one of the following parameters: readfds if you want to know when any of the sockets in the set is ready to recv() data, writefds if any of the sockets is ready to send() data to, and/or exceptfds if you need to know when an exception (error) occurs on any of the sockets. Any or all of these parameters can be NULL if you're not interested in those types of events. After select() returns, the values in the sets will be changed to show which are ready for reading or writing, and which have exceptions.
The first parameter, n is the highest-numbered socket
descriptor (they're just
Lastly, the
The helper macros do the following:
Add fd to the set. |
|
Remove fd from the set. |
|
Return true if fd is in the set. |
|
Clear all entries from the set. |
Returns the number of descriptors in the set on success, 0 if the timeout was reached, or -1 on error (and errno will be set accordingly.) Also, the sets are modified to show which sockets are ready.
int s1, s2, n; fd_set readfds; struct timeval tv; char buf1[256], buf2[256]; // pretend we've connected both to a server at this point //s1 = socket(...); //s2 = socket(...); //connect(s1, ...)... //connect(s2, ...)... // clear the set ahead of time FD_ZERO(&readfds); // add our descriptors to the set FD_SET(s1, &readfds); FD_SET(s2, &readfds); // since we got s2 second, it's the "greater", so we use that for // the n param in select() n = s2 + 1; // wait until either socket has data ready to be recv()d (timeout 10.5 secs) tv.tv_sec = 10; tv.tv_usec = 500000; rv = select(n, &readfds, NULL, NULL, &tv); if (rv == -1) { perror("select"); // error occurred in select() } else if (rv == 0) { printf("Timeout occurred! No data after 10.5 seconds.\n"); } else { // one or both of the descriptors have data if (FD_ISSET(s1, &readfds)) { recv(s1, buf1, sizeof buf1, 0); } if (FD_ISSET(s2, &readfds)) { recv(s1, buf2, sizeof buf2, 0); } }
<< Prev | Beej's Guide to Network Programming | Next >> |