After many tries I couldn't get my select()
work. I'm so lost! I'm gettin -1
as a result. I'm following this guide.
listen(sock, MAXQUEUE);
build_select_list(sock, connectlist, highsock, socks);
readsocks = select(FD_SETSIZE, &socks, (fd_set *) 0, (fd_set *) 0,
NULL );
These are the functions I'm using:
void build_select_list(int sock, int connectlist[], int highsock, fd_set socks) {
int listnum;
FD_ZERO(&socks);
FD_SET(sock, &socks);
/* Loops through all the possible connections and adds
those sockets to the fd_set */
for (listnum = 0; listnum < MAXQUEUE; listnum++) {
if (connectlist[listnum] != 0) {
FD_SET(connectlist[listnum], &socks);
if (connectlist[listnum] > highsock)
highsock = connectlist[listnum];
}
}}
And this is how I get my listener's file descriptor:
int socketServer(char* portNumber) {
int sockfd; // listen on sock_fd, new connection on new_fd
struct addrinfo hints, *servinfo, *p;
struct sigaction sa;
int yes = 1;
int rv;
memset(&hints, 0, sizeof hints);
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; // use my IP
if ((rv = getaddrinfo(NULL, portNumber, &hints, &servinfo)) != 0) {
fprintf(stderr, "getaddrinfo: %s\n", gai_strerror(rv));
return 1;
}
// loop through all the results and bind to the first we can
for (p = servinfo; p != NULL ; p = p->ai_next) {
if ((sockfd = socket(p->ai_family, p->ai_socktype, p->ai_protocol))
== -1) {
perror("server: socket");
continue;
}
if (setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(int))
== -1) {
perror("setsockopt");
exit(1);
}
if (bind(sockfd, p->ai_addr, p->ai_addrlen) == -1) {
close(sockfd);
perror("server: bind");
continue;
}
break;
}
if (p == NULL ) {
fprintf(stderr, "server: failed to bind\n");
return 2;
}
freeaddrinfo(servinfo); // all done with this structure
if (listen(sockfd, BACKLOG) == -1) {
perror("listen");
exit(1);
}
sa.sa_handler = sigchld_handler; // reap all dead processes
sigemptyset(&sa.sa_mask);
sa.sa_flags = SA_RESTART;
if (sigaction(SIGCHLD, &sa, NULL ) == -1) {
perror("sigaction");
exit(1);
}
return sockfd;
}
Your build_select_list
function takes a copy of the set, and modifies only that local copy. Pass it "by reference", just like you do to the select
function.
And of course you have to call this function every time you before you call select
, as the select
function modifies the set.