change implement of timeout_recv

This commit is contained in:
ubuntu201711081 2020-12-04 04:39:58 +00:00
parent eca169cd4f
commit 923349635d
5 changed files with 26 additions and 40 deletions

View File

@ -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)

View File

@ -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;

View File

@ -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){

View File

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

View File

@ -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);
/*