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