poll函数与select类似,最显著的区别是提供fd的方式不一样。
要让poll监控文件描述符的话,需要提供一个struct pollfd的数组。
/* Data structure describing a polling request. */
int fd; /* File descriptor to poll. */
short int events; /* Types of events poller cares about. */
short int revents; /* Types of events that actually occurred. */
其中fd是文件描述符,events是需要监控的事件,revents是实际发生的事件。
当监控的事件时,poll函数会修改struct pollfd数组里每个pollfd.revents。
/* Event types that can be polled for. These bits may be set in `events'
to indicate the interesting event types; they will appear in `revents'
to indicate the status of the file descriptor. */
#define POLLIN 0x001 /* There is data to read. */
#define POLLPRI 0x002 /* There is urgent data to read. */
#define POLLOUT 0x004 /* Writing now will not block. */
#if defined __USE_XOPEN || defined __USE_XOPEN2K8
/* These values are defined in XPG4.2. */
# define POLLRDNORM 0x040 /* Normal data may be read. */
# define POLLRDBAND 0x080 /* Priority data may be read. */
# define POLLWRNORM 0x100 /* Writing now will not block. */
# define POLLWRBAND 0x200 /* Priority data may be written. */
/* These are extensions for Linux. */
# define POLLREMOVE 0x1000
# define POLLRDHUP 0x2000
/* Event types always implicitly polled for. These bits need not be set in
`events', but they will appear in `revents' to indicate the status of
#define POLLERR 0x008 /* Error condition. */
#define POLLHUP 0x010 /* Hung up. */
#define POLLNVAL 0x020 /* Invalid polling request. */
下面这个例子监听4444端口,结合poll来管理多个网络连接。
int do_listen(char* ip, int port, int backlog)
if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0 )
setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&opt,sizeof(opt));
struct sockaddr_in servaddr;
servaddr.sin_family = AF_INET;
inet_pton(AF_INET, ip, &servaddr.sin_addr);
servaddr.sin_port = htons(port);
if(bind(fd, (struct sockaddr*)&servaddr, sizeof(servaddr) ) < 0)
int do_poll(int sock, int maxfd)
struct sockaddr_in clientaddr;
socklen_t socklen = sizeof(clientaddr);
struct pollfd fds[maxfd];
for(; ++i < maxfd; fds[i].fd=-1);
char hello[10] = "hello";
int ok = poll(fds, max, -1);
printf("poll error: %s\n", strerror(errno));
if(fds[0].revents & POLLIN == POLLIN)
if((conn = accept(sock, (struct sockaddr*)&clientaddr, &socklen)) < 0)
if(errno == EINTR) continue;
printf("accept error: %s\n", strerror(errno));
printf("drop connect: %s:%d\n", inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port);
printf("accept: %d, %s:%d\n", conn, inet_ntoa(clientaddr.sin_addr), clientaddr.sin_port);
printf("from client...\n");
if(fds[i].fd < 0) continue;
if(fds[i].revents & POLLIN)
cnt = read(fds[i].fd, buf, BUFSIZ);
if(cnt == 0 || *buf == EOF)
printf("from client: %s", buf);
write(fds[i].fd, hello, 5);
write(fds[i].fd, buf, cnt);
int sock = do_listen("0.0.0.0", 4444, 100);
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26239116/viewspace-2075383/,如需转载,请注明出处,否则将追究法律责任。