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
 | 
			
		||||
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)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										1
									
								
								client.c
									
										
									
									
									
								
							
							
						
						
									
										1
									
								
								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;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										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);
 | 
			
		||||
    int csock;
 | 
			
		||||
    int bufsize;
 | 
			
		||||
    register_alarm();
 | 
			
		||||
    sock = socket(AF_INET,SOCK_STREAM,0);
 | 
			
		||||
    atexit(safe_exit);
 | 
			
		||||
    if(sock < 0){
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -4,6 +4,8 @@
 | 
			
		|||
#include <errno.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -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);
 | 
			
		||||
/*
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		
		Reference in a new issue