change implement of timeout_recv
This commit is contained in:
parent
eca169cd4f
commit
923349635d
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…
Reference in New Issue
Block a user