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);
}