C++ poll()不';似乎看不到UDP套接字上的事件
我正在尝试使用C++ poll()不';似乎看不到UDP套接字上的事件,c++,sockets,udp,C++,Sockets,Udp,我正在尝试使用poll()编写一个web程序。我正在struct pollfd数组中创建一个UDP,然后轮询它。但是,poll()每次都返回0,无论我向它发送了多少次消息。当我只调用recvfrom时,它工作得很好。这是我的代码: 创建和绑定套接字: struct pollfd[2] fds; // ... fds[0].fd = socket(AF_INET, SOCK_DGRAM, 0); if (fds[0].fd < 0) syserr("socket"); listen_
poll()
编写一个web程序。我正在struct pollfd
数组中创建一个UDP
,然后轮询它。但是,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");
struct pollfd[2]fds;
// ...
fds[0].fd=socket(AF_INET,SOCK_DGRAM,0);
if(fds[0].fd<0)
系统错误(“套接字”);
侦听地址={0};
listen\u address.sin\u family=AF\u INET;
侦听地址sin地址s地址=htonl(INADDR\U ANY);
listen_address.sin_port=htons(m_port);
如果(绑定)(
fds[0].fd,
(结构sockaddr*)和侦听地址,
(socklen_t)sizeof(侦听地址)
) < 0)
系统错误(“绑定”);
现在,这项工作:
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;
}
(;;)的{
memset(缓冲区,0,BUF_大小+1);
rval=recvfrom(
fds[0].fd,
缓冲器
大小,
0,
(结构sockaddr*)和响应地址,
&rcva_len
);
std::cout使用poll()的方式有两个关键问题:
您必须为每个文件描述符设置revents
字段,以指示您感兴趣的事件,例如POLLIN
和/或POLLOUT
。您的代码无法将revents
设置为任何内容
poll()
的第三个参数是超时设置。您将其设置为0。这意味着“检查文件描述符是否发生了任何请求的事件,但在任何情况下总是立即返回,如果没有文件描述符包含请求的事件,则返回0”
这就是你看到的行为
为了等待任何文件描述符的事件发生,我不告诉您需要将第三个参数设置为什么,而是让您参考poll()
的手册页。阅读手册页很好。手册页解释了一切
总之:
正确初始化每个文件描述符的revents
参数
将正确的参数传递给poll()
,如手册页所述。如果希望poll()
无限期地等待,直到传递的任何文件描述符请求的事件发生,则有一个特定的值来执行此操作。请查找它
返回poll()
后,检查每个文件描述符的事件
参数以确定文件描述符的状态
使用poll()
的方式有两个关键问题:
您必须为每个文件描述符设置revents
字段,以指示您感兴趣的事件,例如POLLIN
和/或POLLOUT
。您的代码无法将revents
设置为任何内容
poll()
的第三个参数是超时设置。您将其设置为0。这意味着“检查文件描述符是否发生了任何请求的事件,但在任何情况下总是立即返回,如果没有文件描述符包含请求的事件,则返回0”
这就是你看到的行为
为了等待任何文件描述符的事件发生,我不告诉您需要将第三个参数设置为什么,而是让您参考poll()
的手册页。阅读手册页很好。手册页解释了一切
总之:
正确初始化每个文件描述符的revents
参数
将正确的参数传递给poll()
,如手册页所述。如果希望poll()
无限期地等待,直到传递的任何文件描述符请求的事件发生,则有一个特定的值来执行此操作。请查找它
返回poll()
后,检查每个文件描述符的事件
参数以确定文件描述符的状态
不要SMAP标签。这是C++,不是C,而且,不是,库源代码的语言没有关系!不要SMAP标签。这是C++,不是C。而且,不,库源代码的语言也没关系!谢谢,我从来没有觉得太舒服了。
,但我几乎不知道这意味着什么,直到你在这里解释好了,你真的需要弄清楚如何更“舒适”阅读手册页。学习如何阅读和理解技术规范是一项强制性的技能,不仅仅是对每一个C++开发者,而是对任何语言或IT技能的开发者。只是一个建议。现在这是一个很好的机会:打开民意调查手册页,开始阅读,不要停下来,直到你理解它的每一个字。最后再看几遍。这可能会花你几个小时,但时间会花得很好。不仅仅是通过学习poll(),而是通过学习如何阅读手册页。当然你是对的,我实际上指的是linux手册页,它碰巧是以一种非常具体的方式编写的。那么我最好开始我的家庭作业。谢谢你的建议“revents”和“events”是交换的。“events”是一个输入,“revents”是一个输出Hanks很多,我从来没有对手册页感到太舒服过。它提到短事件输入事件标志(见下文)
,但在你解释之前我几乎不知道这意味着什么。好吧,你真的需要弄清楚如何更“舒服”阅读手册页。学习如何阅读和理解技术规范不仅是每一个C++开发者的必备技能,也是任何语言或IT技能的开发者的一个必备技能。只是一个建议。这对你来说是个好机会:打开民意调查手册页,开始阅读,不要停下来,直到你明白为止。
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>