Compare commits
6 Commits
9ff0082313
...
50eb6f4cf7
Author | SHA1 | Date | |
---|---|---|---|
|
50eb6f4cf7 | ||
|
aaeba28fb8 | ||
|
226a0fbdc6 | ||
|
9d012b2c6c | ||
|
31535a0574 | ||
|
61830ba554 |
16
Makefile
16
Makefile
@ -1,6 +1,8 @@
|
|||||||
CC = gcc
|
CC = gcc
|
||||||
CFLAGS = -lm -Wall -O2
|
CFLAGS = -lm -Wall -O2
|
||||||
Bin = server client p-server p-client
|
ServerBin = server p-server
|
||||||
|
ClientBin = client p-client
|
||||||
|
Bin = $(ServerBin) $(ClientBin)
|
||||||
|
|
||||||
all:
|
all:
|
||||||
make $(Bin)
|
make $(Bin)
|
||||||
@ -16,7 +18,17 @@ p-server: socket_wrapper.o p-server.c
|
|||||||
$(CC) -o p-server p-server.c socket_wrapper.o $(CFLAGS)
|
$(CC) -o p-server p-server.c socket_wrapper.o $(CFLAGS)
|
||||||
p-client: socket_wrapper.o p-client.c
|
p-client: socket_wrapper.o p-client.c
|
||||||
$(CC) -o p-client p-client.c socket_wrapper.o $(CFLAGS)
|
$(CC) -o p-client p-client.c socket_wrapper.o $(CFLAGS)
|
||||||
|
p-slowclient: socket_wrapper.o p-client.c
|
||||||
|
$(CC) -o p-slowclient p-client.c socket_wrapper.o $(CFLAGS) -D SLOW_CLIENT=10
|
||||||
|
|
||||||
.PHONY: clean
|
.PHONY: clean moveall
|
||||||
clean:
|
clean:
|
||||||
rm *.o $(Bin)
|
rm *.o $(Bin)
|
||||||
|
rm $(addprefix client_test/,$(ClientBin))
|
||||||
|
rm $(addprefix server_test/,$(ServerBin))
|
||||||
|
|
||||||
|
moveall:
|
||||||
|
mv client client_test/client
|
||||||
|
mv p-client client_test/p-client
|
||||||
|
mv server server_test/server
|
||||||
|
mv p-server server_test/p-server
|
@ -10,9 +10,14 @@ Usage:
|
|||||||
./client SERVERNAME PORT FILENAME
|
./client SERVERNAME PORT FILENAME
|
||||||
```
|
```
|
||||||
|
|
||||||
available macro:
|
Server OPTION and arguments:
|
||||||
|
- `-p port` :set to port binding. couldn't set to 0
|
||||||
|
- `-h` :print help message.
|
||||||
|
|
||||||
|
Available macro:
|
||||||
- DEFAULT_SERVER_PORT : 9091
|
- DEFAULT_SERVER_PORT : 9091
|
||||||
- DEFAULT_MAX_PATH_SIZE : 256(must be less than 1000)
|
- DEFAULT_MAX_PATH_SIZE : 256(must be less than 1000)
|
||||||
- TIMEOUT : 5(second unit)
|
- TIMEOUT : 5(second unit)
|
||||||
- USE_SENDFILE
|
- USE_SENDFILE
|
||||||
- DEFAULT_SEND_FILE_CHUNK_SIZE : 0x100000(1MB)
|
- DEFAULT_SEND_FILE_CHUNK_SIZE : 0x100000(1MB)
|
||||||
|
- SLOW_CLIENT(second unit)
|
@ -39,6 +39,9 @@ int sendReadOp(int sock,const char * filename){
|
|||||||
perror("readop send fail");
|
perror("readop send fail");
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
#ifdef SLOW_CLIENT
|
||||||
|
sleep(SLOW_CLIENT);
|
||||||
|
#endif
|
||||||
if(send(sock,filename,op.file_url_size,0)<0){
|
if(send(sock,filename,op.file_url_size,0)<0){
|
||||||
perror("readop filename send fail");
|
perror("readop filename send fail");
|
||||||
return -1;
|
return -1;
|
||||||
|
56
p-server.c
56
p-server.c
@ -12,6 +12,7 @@
|
|||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include "socket_wrapper.h"
|
#include "socket_wrapper.h"
|
||||||
|
|
||||||
static const int MAX_LISTEN_SOCKET = 16;
|
static const int MAX_LISTEN_SOCKET = 16;
|
||||||
@ -173,6 +174,39 @@ int send_response(int sock,int fd, uint8_t * buf, size_t bufsize){
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
const char * help(const char * n){
|
||||||
|
const char * msg = "USASE : %s [Option] ...\n"
|
||||||
|
"Options and arguments: \n"
|
||||||
|
"-p port\t:set to port binding. couldn't set to 0\n"
|
||||||
|
"-h\t:print help message.\n";
|
||||||
|
printf(msg,n);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
/** return 0 ok. otherwise invalid format*/
|
||||||
|
int parse_args(int argc,const char * argv[] , in_port_t * port){
|
||||||
|
int pos = 1;
|
||||||
|
const char * opt;
|
||||||
|
while (pos < argc)
|
||||||
|
{
|
||||||
|
opt = argv[pos++];
|
||||||
|
if (strcmp(opt,"-h") == 0 || strcmp(opt,"--help") == 0)
|
||||||
|
{
|
||||||
|
help(argv[0]);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else if(strcmp(opt,"-p") == 0 || strcmp(opt,"--port") == 0){
|
||||||
|
if (pos < argc){
|
||||||
|
const char * value = argv[pos++];
|
||||||
|
*port = atoi(value);
|
||||||
|
if (port == 0){ // either not number or zero
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else return 2; //failed to find argument.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
static int sock;
|
static int sock;
|
||||||
void safe_exit(){
|
void safe_exit(){
|
||||||
close(sock);
|
close(sock);
|
||||||
@ -185,6 +219,11 @@ int main(int argc, const char *argv[]){
|
|||||||
int csock;
|
int csock;
|
||||||
int bufsize;
|
int bufsize;
|
||||||
int i;
|
int i;
|
||||||
|
in_port_t binding_port_number = SERVER_PORT;
|
||||||
|
if (argc > 1){
|
||||||
|
int d = parse_args(argc,argv,&binding_port_number);
|
||||||
|
if(d != 0 ) return d;
|
||||||
|
}
|
||||||
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){
|
||||||
@ -206,7 +245,7 @@ int main(int argc, const char *argv[]){
|
|||||||
|
|
||||||
addr.sin_addr.s_addr = htonl(INADDR_ANY); /*0.0.0.0 모든 네트워크 인터페이스에 묶임.*/
|
addr.sin_addr.s_addr = htonl(INADDR_ANY); /*0.0.0.0 모든 네트워크 인터페이스에 묶임.*/
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(SERVER_PORT);
|
addr.sin_port = htons(binding_port_number);
|
||||||
|
|
||||||
if(bind(sock, (struct sockaddr *)&addr,sizeof(addr)) < 0){
|
if(bind(sock, (struct sockaddr *)&addr,sizeof(addr)) < 0){
|
||||||
perror("bind failed");
|
perror("bind failed");
|
||||||
@ -215,7 +254,7 @@ int main(int argc, const char *argv[]){
|
|||||||
char ip_buf[INET_ADDRSTRLEN];
|
char ip_buf[INET_ADDRSTRLEN];
|
||||||
const char * msg = inet_ntop(AF_INET,&addr.sin_addr,ip_buf,sizeof(ip_buf));
|
const char * msg = inet_ntop(AF_INET,&addr.sin_addr,ip_buf,sizeof(ip_buf));
|
||||||
assert(msg != NULL);
|
assert(msg != NULL);
|
||||||
fprintf(stderr,"server bind on %s:%d\n",msg ,SERVER_PORT);
|
fprintf(stderr,"server bind on %s:%d\n",msg ,binding_port_number);
|
||||||
}
|
}
|
||||||
if(listen(sock,MAX_LISTEN_SOCKET) < 0){
|
if(listen(sock,MAX_LISTEN_SOCKET) < 0){
|
||||||
perror("listen failed");
|
perror("listen failed");
|
||||||
@ -227,6 +266,7 @@ int main(int argc, const char *argv[]){
|
|||||||
int fd, pid;
|
int fd, pid;
|
||||||
char ip_buf[INET_ADDRSTRLEN];
|
char ip_buf[INET_ADDRSTRLEN];
|
||||||
const char * msg;
|
const char * msg;
|
||||||
|
int retval = 0;
|
||||||
if((csock = accept(sock, (struct sockaddr *)&client_addr,&client_addr_len)) < 0){
|
if((csock = accept(sock, (struct sockaddr *)&client_addr,&client_addr_len)) < 0){
|
||||||
free(buf);
|
free(buf);
|
||||||
perror("accept error");
|
perror("accept error");
|
||||||
@ -237,15 +277,23 @@ int main(int argc, const char *argv[]){
|
|||||||
pid = fork();
|
pid = fork();
|
||||||
if(pid == 0){
|
if(pid == 0){
|
||||||
if((fd = read_request(csock,buf,bufsize)) > 0){
|
if((fd = read_request(csock,buf,bufsize)) > 0){
|
||||||
send_response(csock,fd,buf,bufsize);
|
retval = send_response(csock,fd,buf,bufsize);
|
||||||
close(fd);
|
close(fd);
|
||||||
}
|
}
|
||||||
|
else retval = fd;
|
||||||
if(close(csock) < 0)
|
if(close(csock) < 0)
|
||||||
perror("csock close error");
|
perror("csock close error");
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return retval;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
int pid = wait(&retval);
|
||||||
|
printf("[%d] %d: %d\n",i,pid,retval);
|
||||||
|
}
|
||||||
|
|
||||||
free(buf);
|
free(buf);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
3
pctest.sh
Executable file
3
pctest.sh
Executable file
@ -0,0 +1,3 @@
|
|||||||
|
#! /bin/bash
|
||||||
|
cd client_test
|
||||||
|
./p-slowclient localhost 9091 test.txt & ./p-client localhost 9091 test.txt & ./p-client localhost 9091 test.txt
|
43
server.c
43
server.c
@ -171,6 +171,39 @@ int send_response(int sock,int fd, uint8_t * buf, size_t bufsize){
|
|||||||
#endif
|
#endif
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
const char * help(const char * n){
|
||||||
|
const char * msg = "USASE : %s [Option] ...\n"
|
||||||
|
"Options and arguments: \n"
|
||||||
|
"-p port\t:set to port binding. couldn't set to 0\n"
|
||||||
|
"-h\t:print help message.\n";
|
||||||
|
printf(msg,n);
|
||||||
|
return msg;
|
||||||
|
}
|
||||||
|
/** return 0 ok. otherwise invalid format*/
|
||||||
|
int parse_args(int argc,const char * argv[] , in_port_t * port){
|
||||||
|
int pos = 1;
|
||||||
|
const char * opt;
|
||||||
|
while (pos < argc)
|
||||||
|
{
|
||||||
|
opt = argv[pos++];
|
||||||
|
if (strcmp(opt,"-h") == 0 || strcmp(opt,"--help") == 0)
|
||||||
|
{
|
||||||
|
help(argv[0]);
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
else if(strcmp(opt,"-p") == 0 || strcmp(opt,"--port") == 0){
|
||||||
|
if (pos < argc){
|
||||||
|
const char * value = argv[pos++];
|
||||||
|
*port = atoi(value);
|
||||||
|
if (port == 0){ // either not number or zero
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else return 2; //failed to find argument.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int sock;
|
static int sock;
|
||||||
void safe_exit(){
|
void safe_exit(){
|
||||||
@ -183,6 +216,12 @@ 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;
|
||||||
|
in_port_t binding_port_number = SERVER_PORT;
|
||||||
|
if (argc > 1){
|
||||||
|
int d = parse_args(argc,argv,&binding_port_number);
|
||||||
|
if(d != 0 ) return d;
|
||||||
|
}
|
||||||
|
|
||||||
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){
|
||||||
@ -204,7 +243,7 @@ int main(int argc, const char *argv[]){
|
|||||||
|
|
||||||
addr.sin_addr.s_addr = htonl(INADDR_ANY); /*0.0.0.0 모든 네트워크 인터페이스에 묶임.*/
|
addr.sin_addr.s_addr = htonl(INADDR_ANY); /*0.0.0.0 모든 네트워크 인터페이스에 묶임.*/
|
||||||
addr.sin_family = AF_INET;
|
addr.sin_family = AF_INET;
|
||||||
addr.sin_port = htons(SERVER_PORT);
|
addr.sin_port = htons(binding_port_number);
|
||||||
|
|
||||||
if(bind(sock, (struct sockaddr *)&addr,sizeof(addr)) < 0){
|
if(bind(sock, (struct sockaddr *)&addr,sizeof(addr)) < 0){
|
||||||
perror("bind failed");
|
perror("bind failed");
|
||||||
@ -213,7 +252,7 @@ int main(int argc, const char *argv[]){
|
|||||||
char ip_buf[INET_ADDRSTRLEN];
|
char ip_buf[INET_ADDRSTRLEN];
|
||||||
const char * msg = inet_ntop(AF_INET,&addr.sin_addr,ip_buf,sizeof(ip_buf));
|
const char * msg = inet_ntop(AF_INET,&addr.sin_addr,ip_buf,sizeof(ip_buf));
|
||||||
assert(msg != NULL);
|
assert(msg != NULL);
|
||||||
fprintf(stderr,"server bind on %s:%d\n",msg ,SERVER_PORT);
|
fprintf(stderr,"server bind on %s:%d\n",msg ,binding_port_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(listen(sock,1) < 0){
|
if(listen(sock,1) < 0){
|
||||||
|
@ -24,7 +24,7 @@ int getBufferSizeFrom(int sock){
|
|||||||
|
|
||||||
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 = 0;
|
||||||
int poll_ret;
|
int poll_ret;
|
||||||
struct pollfd fd_single;
|
struct pollfd fd_single;
|
||||||
fd_single.fd = fd;
|
fd_single.fd = fd;
|
||||||
@ -32,19 +32,15 @@ ssize_t timeout_recv(int fd,void * buf,size_t n,int timeout)
|
|||||||
poll_ret = (poll(&fd_single,1,timeout * 1000));
|
poll_ret = (poll(&fd_single,1,timeout * 1000));
|
||||||
if (poll_ret < 0) return -1;
|
if (poll_ret < 0) return -1;
|
||||||
else if(poll_ret == 0) return -2;
|
else if(poll_ret == 0) return -2;
|
||||||
switch (fd_single.revents){
|
if (fd_single.revents & POLLHUP) //We'll treat hangups state like timeouts state.
|
||||||
case POLLHUP: //We'll treat hangups state like timeouts state.
|
|
||||||
return -2;
|
return -2;
|
||||||
case POLLERR:
|
if ((fd_single.revents & POLLERR) || (fd_single.revents & POLLNVAL))
|
||||||
case POLLNVAL:
|
|
||||||
return -1;
|
return -1;
|
||||||
case POLL_IN:
|
if (fd_single.revents & POLL_IN)
|
||||||
ret = recv(fd,buf,n,0);
|
ret = recv(fd,buf,n,0);
|
||||||
assert(ret != 0);
|
assert(ret != 0);
|
||||||
return ret;
|
return ret;
|
||||||
default:
|
|
||||||
assert(0 && "unreachable");
|
|
||||||
}
|
|
||||||
assert(0 && "unreachable");
|
assert(0 && "unreachable");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user