Reputation: 1116
I'm trying to write a web program, using poll()
. I'm creating a UDP
in a struct pollfd
array, and then polling it. However, the poll()
returns 0 every time, no matter how many times I send it a message. When I just call recvfrom
, it works just fine. So here's my code:
Creating and binding the socket:
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");
Now this works:
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;
}
But this doesn't
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);
For testing, I use a command like this
echo -n “foo” | nc -4u -w1 <host> <udp port>
I would appreciate some insight
Upvotes: 0
Views: 1278
Reputation: 118425
There are two critical problems with the way that you use poll()
:
You must set the revents
field, for each file descriptor, to indicate which events you are interested in, such as POLLIN
and/or POLLOUT
. Your code fails to set revents
to anything.
The third parameter to poll()
is the timeout setting. Which you are setting to 0. This means "check the file descriptors for whether or not any of the requested events
have occured, but always return immediately in any case, and if no file descriptors have the requested events then return 0".
Which is the behavior you are seeing.
Instead of telling you what you need to set the third parameter to, in order to wait until any of the file descriptors's events have occured, I'll just refer you to poll()
's manual page. Reading manual pages is good. They explain everything.
In conclusion:
Initialize each file descriptor's revents
parameter properly.
Pass the correct parameters to poll()
, as described in its manual page. If you want poll()
to wait indefinitely, until any of the passed file descriptors' requested events have occured, there's a specific value to do this. Look it up.
After poll()
returns, check each file descriptor's events
parameter to determine the file descriptor's status.
Upvotes: 2