TheMountainThatCodes TheMountainThatCodes - 3 months ago 10
C++ Question

What causes error in the poll() function, c++?

I'm fairly new to socket programming, and I'm trying to write a program that would get incoming tcp connections and manage them somehow. I can't figure out why the following code is giving me a "poll error":

int main(int argc, char *argv[]) {
char *port;
struct pollfd connections[MAX_CONNECTIONS];
struct addrinfo addr_hints, *addr_result;
int ret, i;

for (i = 0; i < MAX_CONNECTIONS; ++i) {
connections[i].fd = -1;
connections[i].events = POLLIN;
connections[i].revents = 0;
}

port = "0";

memset(&addr_hints, 0, sizeof(struct addrinfo));
addr_hints.ai_flags = AI_PASSIVE;
addr_hints.ai_family = AF_UNSPEC;
addr_hints.ai_socktype = SOCK_STREAM;
addr_hints.ai_protocol = IPPROTO_TCP;

getaddrinfo(NULL, port, &addr_hints, &addr_result);

connections[0].fd = socket(addr_result->ai_family, addr_result->ai_socktype, addr_result->ai_protocol);

if (connections[0].fd < 0) {
cerr << "Socket error" << endl;
return 0;
}

if (bind(connections[0].fd, addr_result->ai_addr, addr_result->ai_addrlen) < 0) {
cerr << "Bind errror" << endl;
return 0;
}

if (listen(connections[0].fd, 25) < 0) {
cerr << "Listen error" << endl;
return 0;
}

do {
for (i = 0; i < MAX_CONNECTIONS; ++i)
connections[i].revents = 0;

ret = poll(connections, MAX_CONNECTIONS, -1);

if (ret < 0) {
cerr << "Poll error" << endl;
return 0;
} else {
//DO SOMETHING
}

} while(true);
}


MAX_CONNECTIONS is a constant set to 10000. Connections[0] is supposed to be the descriptor on which i am listening to incoming connections. I set port to "0" because i want to pick a random port. It seems that the poll function fails immediately, yielding the message "Poll error" (so poll() was less than 0 basically). I've checked and after poll and bind connections[0] has a file descriptor. I'm not sure what I'm doing wrong, is it something with the getaddrinfo function?

Answer

The problem is that your file descriptor array for poll is too large. The maximum size it can be is defined as RLIMIT_NOFILE. This is likely 1024 for your system. Reduce MAXIMUM_CONNECTIONS to this value or less.

From the poll spec:

EINVAL The nfds value exceeds the RLIMIT_NOFILE value.

See more at: http://man7.org/linux/man-pages/man2/poll.2.html

Comments