I'm new to socket programming, and it's hard for me to understand how select()
and FD_SET()
.
I am modifying an example from the Bay textbook, trying to understand it. What I want to do in the for loop is at each iteration, I wait 4 seconds. If reading is available, I would print βThe key was pressed,β and if it will time out, then it will print βTimeoutβ. Then I cleaned the kit and repeated the process another 9 times. But it seems that after the file descriptor 0 is set, it will never be canceled even after calling FD_ZERO()
and / or FD_CLR()
. In other words, after I press the key in the first iteration of the loop, the file descriptor is set for the remaining iterations and is no longer executed. So something must be missing, but I donβt know what.
#include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <errno.h> #include <string.h> #include <sys/types.h> #include <sys/socket.h> #include <netinet/in.h> #include <arpa/inet.h> #include <netdb.h> #define SERVERPORT 4950 int main(int argc, char *argv[]) { struct sockaddr_in their_addr; // connector address information struct hostent *he; int numbytes; int broadcast = 1; if ((he=gethostbyname(argv[1])) == NULL) { // get the host info perror("gethostbyname"); exit(1); } // this call is what allows broadcast packets to be sent: if (setsockopt(sockfd, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof broadcast) == -1) { perror("setsockopt (SO_BROADCAST)"); exit(1); } their_addr.sin_family = AF_INET; // host byte order their_addr.sin_port = htons(SERVERPORT); // short, network byte order their_addr.sin_addr = *((struct in_addr *)he->h_addr); memset(their_addr.sin_zero, '\0', sizeof their_addr.sin_zero); struct timeval tv; fd_set broadcastfds; int i; for(i=0; i < 10; i++) { tv.tv_sec = 4; tv.tv_usec = 500000; FD_ZERO(&broadcastfds); FD_CLR(0, &broadcastfds); FD_SET(0, &broadcastfds); if(select(0+1, &broadcastfds, NULL, NULL, &tv) == -1) perror("select"); if (FD_ISSET(0, &broadcastfds)) printf("A key was pressed!\n"); else printf("Timed out.\n"); fflush(stdout); } close(sockfd); return 0; }
source share