我想知道当轮询设置这些位时应该做什么? closures套接字,忽略它或什么?
POLLHUP
表示插座不再连接。 在TCP中,这意味着FIN已经收到并发送。
POLLERR
表示套接字出现异步错误。 在TCP中,这通常意味着RST已被接收或发送。 如果文件描述符不是套接字, POLLERR
可能意味着设备不支持轮询。
对于上述两种情况,套接字文件描述符仍处于打开状态,尚未关闭(但shutdown()
可能已经被调用)。 文件描述符上的close()
将释放仍然代表套接字保留的资源。 理论上,应该可以立即重用套接字(例如,用另一个connect()
调用)。
POLLNVAL
表示套接字文件描述符未打开。 close()
它将是一个错误。
这取决于确切的错误性质。 使用getsockopt()来查看问题:
int error = 0; socklen_t errlen = sizeof(error); getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&error, &errlen);
价值观: http : //www.xinotes.net/notes/note/1793/
最简单的方法是假定套接字在任何情况下都不再可用并关闭它。
POLLNVAL
表示文件描述符的值是无效的。 它通常表示程序中有错误,但是如果您关闭了文件描述符,并且从那以后可能重用了描述符,则您可以依赖poll
返回POLLNVAL
。
POLLERR
类似于来自select
错误事件。 它表示read
或write
调用会返回错误状态(例如I / O错误)。 这不包括通过其errorfds
掩码select
信号但是通过POLLPRI
poll
信号的带外数据。
POLLHUP
基本上意味着连接的另一端已经关闭了连接的结束。 POSIX将其描述为
该设备已断开连接。 这个事件和POLLOUT是互斥的。 如果发生挂断,则流永远不可写入。
对于一个终端来说,这足够清楚了:终端已经消失(产生SIGHUP的相同事件:调制解调器会话已终止,终端仿真器窗口已关闭等)。 POLLHUP
永远不会被发送到一个普通的文件。 对于管道和插座, 取决于操作系统 。 Linux在管道写入结束的程序关闭管道时设置POLLIN|POLLHUP
,并在套接字的另一端关闭套接字时设置POLLIN|POLLHUP
,而仅在套接字关闭时才POLLIN
。 最近* BSD在管道的写入结束时关闭管道,设置POLLIN|POLLUP
,并且套接字的行为更加可变。
最小的FIFO示例
一旦你了解了这些情况发生的时候,应该很容易知道该怎么办。
#define _XOPEN_SOURCE 700 #include <fcntl.h> /* creat, O_CREAT */ #include <poll.h> /* poll */ #include <stdio.h> /* printf, puts, snprintf */ #include <stdlib.h> /* EXIT_FAILURE, EXIT_SUCCESS */ #include <unistd.h> /* read */ int main(void) { char buf[1024]; int fd, n; short revents; struct pollfd pfd; fd = open("poll0.tmp", O_RDONLY | O_NONBLOCK); pfd.fd = fd; pfd.events = POLLIN; while (1) { puts("loop"); poll(&pfd, 1, -1); revents = pfd.revents; if (revents & POLLIN) { n = read(pfd.fd, buf, sizeof(buf)); printf("POLLIN n=%d buf=%.*s\n", n, n, buf); } if (revents & POLLHUP) { printf("POLLHUP\n"); close(pfd.fd); pfd.fd *= -1; } if (revents & POLLNVAL) { printf("POLLNVAL\n"); } if (revents & POLLERR) { printf("POLLERR\n"); } } }
编译:
gcc -o poll.out -std=c99 poll.c
用法:
sudo mknod -m 666 poll0.tmp p ./poll.out
在另一个外壳上:
printf a >poll0.tmp
POLLHUP
如果您不修改源代码: ./poll.out
输出:
loop POLLIN n=1 buf=a loop POLLHUP loop
所以:
POLLIN
printf
关闭时发生POLLHUP
close(pfd.fd);
和pfd.fd *= -1;
干净的事情,我们停止接受POLLHUP
poll
永远挂起 这是正常的操作。
您现在可以编辑FIFO以等待下一个open
,或者如果完成,则退出循环。
POLLNAL
如果你注释掉pfd.fd *= -1;
: ./poll.out
打印:
POLLIN n=1 buf=a loop POLLHUP loop POLLNVAL loop POLLNVAL ...
并永远循环。
所以:
POLLIN
和POLLHUP
和close
一样像以前一样发生 pfd.fd
设置为负数,所以poll
不断尝试使用我们关闭的fd
POLLNVAL
所以我们看到,这不应该发生,并指出您的代码中的错误。
POLLERR
我不知道如何用FIFO生成POLLERR
。 让我知道如果有办法。 但是应该可以使用设备驱动程序的file_operations
。
在Ubuntu 14.04测试。