我正在尝试使用poll()
编写一个网络程序。我在UDP
数组中创建struct pollfd
,然后轮询它。但是,无论我向其发送多少次消息,poll()
每次都返回0。当我打电话给recvfrom
时,它运作得很好。所以这是我的代码:
创建并绑定套接字:
struct pollfd[2] fds;
// ...
fds[0].fd = socket(AF_INET, SOCK_DGRAM, 0);
if (fds[0].fd < 0)
syserr("socket");
listen_address = { 0 };
listen_address.sin_family = AF_INET;
listen_address.sin_addr.s_addr = htonl(INADDR_ANY);
listen_address.sin_port = htons(m_port);
if (bind(
fds[0].fd,
(struct sockaddr*) &listen_address,
(socklen_t) sizeof(listen_address)
) < 0)
syserr("bind");
现在可行:
for (;;) {
memset(buffer, 0, BUF_SIZE + 1);
rval = recvfrom(
fds[0].fd,
buffer,
BUF_SIZE,
0,
(struct sockaddr *) &respond_address,
&rcva_len
);
std::cout << buffer << std::endl;
}
但这不是
finished = false;
do {
fds[0].revents = fds[1].revents = 0;
ret = poll(fds, 2, 0);
if (ret < 0) {
perror("poll");
} else if (ret == 0) {
// the loop always enters here
} else {
// the loop never enters here,
// even though I send messages to the socket
}
} while (!finished);
为了测试,我使用这样的命令
echo -n “foo” | nc -4u -w1 <host> <udp port>
我很感激一些见解
答案 0 :(得分:2)
使用poll()
的方式存在两个严重问题:
您必须为每个文件描述符设置revents
字段,以指明您感兴趣的事件,例如POLLIN
和/或POLLOUT
。您的代码无法将revents
设置为任何内容。
poll()
的第三个参数是超时设置。您将其设置为0.这意味着“检查文件描述符是否已发生任何请求的events
,但在任何情况下始终立即返回,如果没有文件描述符具有请求的事件,则返回0 ”
您所看到的行为是什么。
我没有告诉你需要设置第三个参数,为了等到任何文件描述符的事件发生,我只是引用你到poll()
的手册页。阅读手册页很好。他们解释了一切。
总结:
正确初始化每个文件描述符的revents
参数。
将正确的参数传递给poll()
,如其手册页所述。如果您希望poll()
无限期地等待,直到任何传递的文件描述符请求的事件发生,则有一个特定的值来执行此操作。查一查。
poll()
返回后,检查每个文件描述符的events
参数以确定文件描述符的状态。