Unixではselect関数を使用して、ペンディング中のI/Oをチェックするディスクリプタのリストを指定できる。
int select(int maxDescPlus1, fd_set *readDescs, fd_set *writeDescs, fd_set *exceptionDescs, struct timeval *timeout)
FD_ZERO(fd_set *descriptorVector) : fd_setにあるディスクリプタを全て削除
FD_CLR(int descriptor, fd_set *descriptorVector) : fd_setから削除
FD_SET(int descriptor, fd_set *descriptorVector) : 追加
FD_ISSET(int descriptor, fd_set *descriptorVector)
#include "TCPEchoServer.h" #include <sys/time.h> #include <fcntl.h> int main(int argc, char *argv[]){ int *servSock; int maxDescriptor; fd_set sockSet; long timout; struct timeval setTimeout; int running = 1; int noPorts; int port; unsigned short portNo; if(argc < 3) { fprintf(stderr, "Usage: %s <Timeout(secs.)><Port 1>... \n", argv[0]); exit(1); } timeout = atol(argv[1]); noPorts = argc - 2; servSock = (int *)malloc(noPorts * sizeof(int)); maxDescriptor = -1; for (port = 0; port < noPorts; port++){ portNo = atoi(argv[port + 2]); servSock[port] = CreateTCPServerSocket(portNo); if(servSock[port] > maxDescriptor) maxDescriptor = servSock[port]; } printf("Starting server: Hit return to shutdown\n"); while(running) { FD_ZERO(&sockSet); FD_SET(STDIN_FILENO, &sockSet); for(port = 0; port < noPorts; port++) FD_SET(servSock[port], &sockSet); setTimeout.tv_sec = timeout; setTimeout.tv_usec = 0; if(select(maxDescriptor + 1, &sockSet, NULL, NULL, &selTimout) == 0) printf("No echo request for %ld secs... Server still alive\n", timeout); else { if(FD_ISSET(STDIN_FILENO, &socket)){ printf("Shutting down server\n"); getchar(); running = 0; } for (port = 0; port < noPorts; port++) if(FD_ISSET(servSock[port], &sockSet)){ printf("Request on port %d:", port); HandleTCPClient(AcceptTCPConnection(servSock[port])); } } } for(port = 0; port < noPorts; port++) close(servSock[port]); free(servSock); exit(0); }