#include #include #include #include #include #include #include #include #include #define QLEN 10 #define BUFFSIZE 500 void urg_handler(int); /* must be global so I can recv from handler */ int new_sd; struct timeval tv; int main(int argc, char *argv[]) { struct sockaddr_in my_sin; struct sockaddr_in their_sin; struct sigaction sa; unsigned short port; int sd; int bytes_read; int sin_size; char buff[BUFFSIZE]; fd_set rfds; if (argc != 2 || !((port = atoi(argv[1])) > 0)) { fprintf(stderr, "usage: %s port\n", argv[0]); exit(1); } sd = socket(AF_INET, SOCK_STREAM, 0); if (sd == -1) { perror("socket"); exit(1); } memset(&my_sin, 0, sizeof(struct sockaddr_in)); my_sin.sin_family = AF_INET; my_sin.sin_port = htons(port); my_sin.sin_addr.s_addr = INADDR_ANY; if (bind(sd, (struct sockaddr *)&my_sin, sizeof(my_sin)) == -1) { perror("bind"); exit(1); } if (listen(sd, QLEN) == -1) { perror("listen"); exit(1); } printf("server: listening on port %d\n", port); sa.sa_handler = urg_handler; sa.sa_flags = SA_RESTART; sigemptyset(&(sa.sa_mask)); sigaction(SIGURG, &sa, NULL); while(1) { sin_size = sizeof(their_sin); printf("server: waiting for connection..."); fflush(stdout); new_sd = accept(sd, (struct sockaddr *)&their_sin, &sin_size); if (new_sd < 0) { perror("accept"); exit(1); } if (fcntl(new_sd, F_SETOWN, getpid()) == -1) { perror("fcntl"); exit(1); } printf("\nserver: got a connection from %s\n", inet_ntoa(their_sin.sin_addr)); bytes_read = 1; FD_ZERO(&rfds); tv.tv_sec = 20; tv.tv_usec = 0; while (bytes_read) { FD_SET(new_sd, &rfds); if (!select(new_sd + 1, &rfds, NULL, NULL, &tv)) { bytes_read = 0; printf("server: client timed out after 20 seconds\n"); } else { bytes_read = recv(new_sd, buff, BUFFSIZE, 0); if (bytes_read) { buff[bytes_read] = '\0'; printf("server: read %d bytes, \"%s\"\n", bytes_read, buff); } else { printf("server: remote side closed connection\n"); } } } close(new_sd); } return 0; } void urg_handler(int signo) { char buff[BUFFSIZE]; int bytes_read; /* funky stuff happening here! */ tv.tv_sec = 20; tv.tv_usec = 0; bytes_read = recv(new_sd, buff, BUFFSIZE, MSG_OOB); buff[bytes_read] = '\0'; printf("server: read %d byte(s) of OOB data, \"%s\"\n", bytes_read, buff); }