<< Prev | Beej's Guide to Network Programming | Next >> |
Test for events on multiple sockets simultaneously
#include <sys/poll.h> int poll(struct pollfd *ufds, unsigned int nfds, int timeout);
This function is very similar to select() in that they both watch sets of file descriptors for events, such as incoming data ready to recv(), socket ready to send() data to, out-of-band data ready to recv(), errors, etc.
The basic idea is that you pass an array of nfds
Each element in the array of
struct pollfd { int fd; // the socket descriptor short events; // bitmap of events we're interested in short revents; // when poll() returns, bitmap of events that occurred };
Before calling poll(), load fd with the
socket descriptor (if you set fd to a negative number, this
POLLIN |
Alert me when data is ready to recv() on this socket. |
POLLOUT |
Alert me when I can send() data to this socket without blocking. |
POLLPRI |
Alert me when out-of-band data is ready to recv() on this socket. |
Once the poll() call returns, the revents field will be constructed as a bitwise-OR of the above fields, telling you which descriptors actually have had that event occur. Additionally, these other fields might be present:
POLLERR |
An error has occurred on this socket. |
POLLHUP |
The remote side of the connection hung up. |
POLLNVAL |
Something was wrong with the socket descriptor fd—maybe it's uninitialized? |
Returns the number of elements in the ufds array that have had event occur on them; this can be zero if the timeout occurred. Also returns -1 on error (and errno will be set accordingly.)
int s1, s2; int rv; char buf1[256], buf2[256]; struct pollfd ufds[2]; s1 = socket(PF_INET, SOCK_STREAM, 0); s2 = socket(PF_INET, SOCK_STREAM, 0); // pretend we've connected both to a server at this point //connect(s1, ...)... //connect(s2, ...)... // set up the array of file descriptors. // // in this example, we want to know when there's normal or out-of-band // data ready to be recv()'d... ufds[0].fd = s1; ufds[0].events = POLLIN | POLLPRI; // check for normal or out-of-band ufds[1] = s2; ufds[1].events = POLLIN; // check for just normal data // wait for events on the sockets, 3.5 second timeout rv = poll(ufds, 2, 3500); if (rv == -1) { perror("poll"); // error occurred in poll() } else if (rv == 0) { printf("Timeout occurred! No data after 3.5 seconds.\n"); } else { // check for events on s1: if (ufds[0].revents & POLLIN) { recv(s1, buf1, sizeof buf1, 0); // receive normal data } if (ufds[0].revents & POLLPRI) { recv(s1, buf1, sizeof buf1, MSG_OOB); // out-of-band data } // check for events on s2: if (ufds[1].revents & POLLIN) { recv(s1, buf2, sizeof buf2, 0); } }
<< Prev | Beej's Guide to Network Programming | Next >> |