poll()似乎没有看到UDP套接字上的事件

时间:2016-08-21 15:53:18

标签: c++ sockets udp

我正在尝试使用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>

我很感激一些见解

1 个答案:

答案 0 :(得分:2)

使用poll()的方式存在两个严重问题:

  1. 您必须为每个文件描述符设置revents字段,以指明您感兴趣的事件,例如POLLIN和/或POLLOUT。您的代码无法将revents设置为任何内容。

  2. poll()的第三个参数是超时设置。您将其设置为0.这意味着“检查文件描述符是否已发生任何请求的events,但在任何情况下始终立即返回,如果没有文件描述符具有请求的事件,则返回0 ”

  3. 您所看到的行为是什么。

    我没有告诉你需要设置第三个参数,为了等到任何文件描述符的事件发生,我只是引用你到poll()的手册页。阅读手册页很好。他们解释了一切。

    总结:

    1. 正确初始化每个文件描述符的revents参数。

    2. 将正确的参数传递给poll(),如其手册页所述。如果您希望poll()无限期地等待,直到任何传递的文件描述符请求的事件发生,则有一个特定的值来执行此操作。查一查。

    3. poll()返回后,检查每个文件描述符的events参数以确定文件描述符的状态。