经过多次尝试后,我无法完成select()
工作。我迷路了!结果我开始-1
了。我正在关注this guide。
listen(sock, MAXQUEUE);
build_select_list(sock, connectlist, highsock, socks);
readsocks = select(FD_SETSIZE, &socks, (fd_set *) 0, (fd_set *) 0,
NULL );
这些是我正在使用的功能:
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];
}
}}
这就是我获取监听器文件描述符的方式:
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;
}
答案 0 :(得分:2)
您的build_select_list
函数会获取该集的副本,并仅修改该本地副本。将其“通过引用”传递,就像对select
函数一样。
当然,在您致电select
之前,每次调用此函数时都必须调用此函数,因为select
函数会修改集合。