diff --git a/Makefile b/Makefile index 5405da0..76853c6 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,19 @@ CC = gcc CFLAGS = -lm -Wall -O2 +Bin = server client + all: - make client - make server + make $(Bin) socket_wrapper.o: socket_wrapper.c socket_wrapper.h - $(CC) -c socket_wrapper.c -o socket_wrapper.o $(CFLAGS) + $(CC) -c socket_wrapper.c -o socket_wrapper.o $(CFLAGS) client: socket_wrapper.o client.c $(CC) -o client client.c socket_wrapper.o $(CFLAGS) server: $(CC) -o server server.c socket_wrapper.o $(CFLAGS) +.PHONY: clean clean: - rm *.o server client + rm *.o $(Bin) diff --git a/client.c b/client.c index 964804c..5eee530 100644 --- a/client.c +++ b/client.c @@ -123,7 +123,6 @@ int main(int argc, const char *argv[]){ const char * server_name; in_port_t server_port = SERVER_PORT; int sock; - register_alarm(); if (argc != 4){ fprintf(stderr,"invaild arguments number."); return 1; diff --git a/server.c b/server.c index 1581068..f0dddb9 100644 --- a/server.c +++ b/server.c @@ -147,7 +147,6 @@ int main(int argc, const char *argv[]){ socklen_t client_addr_len = sizeof(client_addr); int csock; int bufsize; - register_alarm(); sock = socket(AF_INET,SOCK_STREAM,0); atexit(safe_exit); if(sock < 0){ diff --git a/socket_wrapper.c b/socket_wrapper.c index f6dc431..fc7d19c 100644 --- a/socket_wrapper.c +++ b/socket_wrapper.c @@ -4,6 +4,8 @@ #include #include #include +#include + #include "socket_wrapper.h" int getBufferSizeFrom(int sock){ @@ -18,39 +20,26 @@ int getBufferSizeFrom(int sock){ return buffer_sz; } -static uint64_t timer_ticks = 0; -static void alarm_handler(int signum){ - timer_ticks++; -} - -void register_alarm(){ - struct sigaction sigact; - sigact.sa_flags = SA_INTERRUPT; - sigemptyset(&sigact.sa_mask); - sigaddset(&sigact.sa_mask,SIGALRM); - sigact.sa_handler = alarm_handler; - sigaction(SIGALRM, &sigact ,NULL); -} - ssize_t timeout_recv(int fd,void * buf,size_t n,int timeout) { ssize_t ret; - uint64_t cur = timer_ticks; - int die_count = 0; - for(;;){ - alarm(timeout); - ret = recv(fd,buf,n,0); - if (ret < 0 && errno == EINTR && cur != timer_ticks) - return -2; - alarm(0); - if (ret == 0){ - usleep(100000); - die_count++; - if(die_count > timeout*10){ - return -2; - } - } - else break; + int poll_ret; + struct pollfd fd_single; + fd_single.fd = fd; + fd_single.events = POLL_IN; + poll_ret = (poll(&fd_single,1,timeout * 1000)); + if (poll_ret < 0) return -1; + else if(poll_ret == 0) return -2; + switch (fd_single.revents){ + case POLLHUP: //We'll treat hangups state like timeouts state. + return -2; + case POLLERR: + case POLLNVAL: + return -1; + case POLL_IN: + return recv(fd,buf,n,0); + default: + assert(0 && "unreachable"); } return ret; } diff --git a/socket_wrapper.h b/socket_wrapper.h index 6bb7fd7..9a2fdac 100644 --- a/socket_wrapper.h +++ b/socket_wrapper.h @@ -43,13 +43,10 @@ struct TransferResult{ int getBufferSizeFrom(int sock); -/*register alarm for timeout_recv()*/ -void register_alarm(); /* return -2 if timeout occur. otherwise, implement equal to 'recv'. -you must call register_alarm() before you use this. -Since alarm() is called by internal implementation, don't use it if other alarms already exist. +`timeout` unit is second. */ ssize_t timeout_recv(int fd,void * buf,size_t n,int timeout); /*