I want to open a port and wait for incoming connections, however I can't get select()
to work. I had it working with poll()
but I need select()
for portability. What am I doing wrong?
Code for waiting for the connection looks like this (I need to check for interruptions every 200ms):
/* Wait for a descriptor */
int wait_for_fd(int fd){
int waitms = 200;
struct timeval tv;
tv.tv_sec = 0;
tv.tv_usec = waitms * 1000;
fd_set rfds;
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
int active = 0;
while(active == 0){
active = select(fd+1, &rfds, NULL, NULL, &tv);
bail_for(active < 0, "select()");
if(pending_interrupt())
break;
}
return active;
}
And then my code to actually open a port and wait for a connection:
int open_port(int port){
// define server socket
struct sockaddr_in serv_addr;
memset(&serv_addr, '0', sizeof(serv_addr));
serv_addr.sin_family = AF_INET;
serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
serv_addr.sin_port = htons(port);
//creates the listening socket
int listenfd = socket(AF_INET, SOCK_STREAM, 0);
bail_for(listenfd < 0, "socket()");
bail_for(bind(listenfd, (struct sockaddr*)&serv_addr, sizeof(serv_addr)) < 0, "bind()");
bail_for(listen(listenfd, 10) < 0, "listen()");
//each accept() is a new incoming connection
printf("Waiting for connetion on port %d...\n", port);
wait_for_fd(listenfd);
int connfd = accept(listenfd, NULL, NULL);
bail_for(connfd < 0, "accept()");
printf("Incoming connection!\n");
//do not allow additional client connetions
close(listenfd);
return connfd;
}
However wait_for_fd()
never returns (due to select always returning 0) even when a client is connecting.
This must be on every iteration:
FD_ZERO(&rfds);
FD_SET(fd, &rfds);
Because rfds
is an in/out parameter for select()
. It actually tells with it which fds were affected.