change implement of timeout_recv
This commit is contained in:
		
							parent
							
								
									eca169cd4f
								
							
						
					
					
						commit
						923349635d
					
				
					 5 changed files with 26 additions and 40 deletions
				
			
		
							
								
								
									
										10
									
								
								Makefile
									
										
									
									
									
								
							
							
						
						
									
										10
									
								
								Makefile
									
										
									
									
									
								
							| 
						 | 
					@ -1,17 +1,19 @@
 | 
				
			||||||
CC = gcc
 | 
					CC = gcc
 | 
				
			||||||
CFLAGS = -lm -Wall -O2
 | 
					CFLAGS = -lm -Wall -O2
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Bin = server client
 | 
				
			||||||
 | 
					
 | 
				
			||||||
all:
 | 
					all:
 | 
				
			||||||
	make client
 | 
						make $(Bin)
 | 
				
			||||||
	make server
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
socket_wrapper.o: socket_wrapper.c socket_wrapper.h
 | 
					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
 | 
					client: socket_wrapper.o client.c
 | 
				
			||||||
	$(CC) -o client client.c socket_wrapper.o $(CFLAGS)
 | 
						$(CC) -o client client.c socket_wrapper.o $(CFLAGS)
 | 
				
			||||||
server:
 | 
					server:
 | 
				
			||||||
	$(CC) -o server server.c socket_wrapper.o $(CFLAGS)
 | 
						$(CC) -o server server.c socket_wrapper.o $(CFLAGS)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.PHONY: clean
 | 
				
			||||||
clean:
 | 
					clean:
 | 
				
			||||||
	rm *.o server client
 | 
						rm *.o $(Bin)
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								client.c
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								client.c
									
										
									
									
									
								
							| 
						 | 
					@ -123,7 +123,6 @@ int main(int argc, const char *argv[]){
 | 
				
			||||||
    const char * server_name;
 | 
					    const char * server_name;
 | 
				
			||||||
    in_port_t server_port = SERVER_PORT;
 | 
					    in_port_t server_port = SERVER_PORT;
 | 
				
			||||||
    int sock;
 | 
					    int sock;
 | 
				
			||||||
    register_alarm();
 | 
					 | 
				
			||||||
    if (argc != 4){
 | 
					    if (argc != 4){
 | 
				
			||||||
        fprintf(stderr,"invaild arguments number.");
 | 
					        fprintf(stderr,"invaild arguments number.");
 | 
				
			||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										1
									
								
								server.c
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								server.c
									
										
									
									
									
								
							| 
						 | 
					@ -147,7 +147,6 @@ int main(int argc, const char *argv[]){
 | 
				
			||||||
    socklen_t client_addr_len = sizeof(client_addr);
 | 
					    socklen_t client_addr_len = sizeof(client_addr);
 | 
				
			||||||
    int csock;
 | 
					    int csock;
 | 
				
			||||||
    int bufsize;
 | 
					    int bufsize;
 | 
				
			||||||
    register_alarm();
 | 
					 | 
				
			||||||
    sock = socket(AF_INET,SOCK_STREAM,0);
 | 
					    sock = socket(AF_INET,SOCK_STREAM,0);
 | 
				
			||||||
    atexit(safe_exit);
 | 
					    atexit(safe_exit);
 | 
				
			||||||
    if(sock < 0){
 | 
					    if(sock < 0){
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -4,6 +4,8 @@
 | 
				
			||||||
#include <errno.h>
 | 
					#include <errno.h>
 | 
				
			||||||
#include <stdlib.h>
 | 
					#include <stdlib.h>
 | 
				
			||||||
#include <unistd.h>
 | 
					#include <unistd.h>
 | 
				
			||||||
 | 
					#include <poll.h>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "socket_wrapper.h"
 | 
					#include "socket_wrapper.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int getBufferSizeFrom(int sock){
 | 
					int getBufferSizeFrom(int sock){
 | 
				
			||||||
| 
						 | 
					@ -18,39 +20,26 @@ int getBufferSizeFrom(int sock){
 | 
				
			||||||
    return buffer_sz;
 | 
					    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 timeout_recv(int fd,void * buf,size_t n,int timeout)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    ssize_t ret;
 | 
					    ssize_t ret;
 | 
				
			||||||
    uint64_t cur = timer_ticks;
 | 
					    int poll_ret;
 | 
				
			||||||
    int die_count = 0;
 | 
					    struct pollfd fd_single;
 | 
				
			||||||
    for(;;){
 | 
					    fd_single.fd = fd;
 | 
				
			||||||
        alarm(timeout);
 | 
					    fd_single.events = POLL_IN;
 | 
				
			||||||
        ret = recv(fd,buf,n,0);
 | 
					    poll_ret = (poll(&fd_single,1,timeout * 1000));
 | 
				
			||||||
        if (ret < 0 && errno == EINTR && cur != timer_ticks)
 | 
					    if (poll_ret < 0) return -1;
 | 
				
			||||||
            return -2;
 | 
					    else if(poll_ret == 0) return -2;
 | 
				
			||||||
        alarm(0);
 | 
					    switch (fd_single.revents){
 | 
				
			||||||
        if (ret == 0){
 | 
					    case POLLHUP: //We'll treat hangups state like timeouts state.
 | 
				
			||||||
            usleep(100000);
 | 
					        return -2;
 | 
				
			||||||
            die_count++;
 | 
					    case POLLERR:
 | 
				
			||||||
            if(die_count > timeout*10){
 | 
					    case POLLNVAL:
 | 
				
			||||||
                return -2;
 | 
					        return -1;
 | 
				
			||||||
            }
 | 
					    case POLL_IN:
 | 
				
			||||||
        }
 | 
					        return recv(fd,buf,n,0);
 | 
				
			||||||
        else break;
 | 
					    default:
 | 
				
			||||||
 | 
					        assert(0 && "unreachable");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    return ret;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -43,13 +43,10 @@ struct TransferResult{
 | 
				
			||||||
 | 
					
 | 
				
			||||||
int getBufferSizeFrom(int sock);
 | 
					int getBufferSizeFrom(int sock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/*register alarm for timeout_recv()*/
 | 
					 | 
				
			||||||
void register_alarm();
 | 
					 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
return -2 if timeout occur.
 | 
					return -2 if timeout occur.
 | 
				
			||||||
otherwise, implement equal to 'recv'.
 | 
					otherwise, implement equal to 'recv'.
 | 
				
			||||||
you must call register_alarm() before you use this.
 | 
					`timeout` unit is second.
 | 
				
			||||||
Since alarm() is called by internal implementation, don't use it if other alarms already exist.
 | 
					 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
ssize_t timeout_recv(int fd,void * buf,size_t n,int timeout);
 | 
					ssize_t timeout_recv(int fd,void * buf,size_t n,int timeout);
 | 
				
			||||||
/*
 | 
					/*
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		
		Reference in a new issue