diff --git a/client.c b/client.c index 5eee530..5601ebd 100644 --- a/client.c +++ b/client.c @@ -121,8 +121,8 @@ int main(int argc, const char *argv[]){ struct sockaddr_in addr; const char * filename; const char * server_name; - in_port_t server_port = SERVER_PORT; - int sock; + in_port_t server_port; + int sock, err; if (argc != 4){ fprintf(stderr,"invaild arguments number."); return 1; @@ -140,17 +140,24 @@ int main(int argc, const char *argv[]){ perror("sock create fail"); return 1; } - { - int option = 1; - if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option)) < 0){ - perror("setsockopt"); + err = getsockaddrbyname(AF_INET,SOCK_STREAM,0,server_name,&addr); + if (err != 0){ + int check; + fprintf(stderr,"netdb fail: %s\n",gai_error(err)); + //assume that sernmae is *.*.*.* and try to parse addr + check = inet_pton(AF_INET,server_name,&addr.sin_addr); + assert(check != -1); + if (check == 0){ + fprintf(stderr,"parsing fail : invaild format\n"); + close(sock); + return 1; } } - addr.sin_addr.s_addr = inet_addr(server_name); addr.sin_family = AF_INET; addr.sin_port = htons(server_port); if(connect(sock,(struct sockaddr *)&addr,sizeof(addr)) < 0){ perror("connect failed"); + close(sock); return 1; } if(sendReadOp(sock,filename) == 0){ diff --git a/server.c b/server.c index a3297ee..474de73 100644 --- a/server.c +++ b/server.c @@ -163,6 +163,12 @@ int main(int argc, const char *argv[]){ perror("sock create fail"); return 1; } + else { + int option = 1; + if(setsockopt(sock,SOL_SOCKET,SO_REUSEADDR,&option,sizeof(option)) < 0){ + perror("setsockopt"); + } + } bufsize = getBufferSizeFrom(sock); buf = malloc(bufsize * sizeof(*buf)); if (buf == NULL){ diff --git a/socket_wrapper.c b/socket_wrapper.c index dab2d4f..4e8ef57 100644 --- a/socket_wrapper.c +++ b/socket_wrapper.c @@ -5,7 +5,8 @@ #include #include #include - +#include +#include #include "socket_wrapper.h" int getBufferSizeFrom(int sock){ @@ -60,4 +61,33 @@ ssize_t recv_until_byte(int fd,void * buf, size_t n,int timeout){ } assert(cur == n); return cur; +} + +int getsockaddrbyname(int domain,int type, int protocol, const char * hostname_str, struct sockaddr * retaddr){ + struct addrinfo hints; + struct addrinfo * result, *entry; + int ret, i; + char hostname[_SC_HOST_NAME_MAX]; + strncpy(hostname,hostname_str,sizeof(hostname)); + memset(&hints,0,sizeof(hints)); + hints.ai_family = domain; + hints.ai_socktype = type; + hints.ai_flags = 0; + hints.ai_protocol = protocol; + + //try 5 times + for (size_t i = 0; i < 5; i++) + { + ret = getaddrinfo(hostname,NULL,&hints,&result); + if(ret == EAI_AGAIN) continue; + else if (ret != 0) return ret; + break; + } + if (ret != 0) return ret; //maybe name server doesn't work properly. + + for (entry = result; entry != NULL; entry = entry->ai_next){ + memcpy(retaddr,entry->ai_addr,sizeof(*retaddr)); + } + freeaddrinfo(result); + return ret; } \ No newline at end of file diff --git a/socket_wrapper.h b/socket_wrapper.h index 7b41c2b..aae57ba 100644 --- a/socket_wrapper.h +++ b/socket_wrapper.h @@ -5,6 +5,7 @@ #include #include #include +#include #ifdef USE_SENDFILE #include @@ -54,10 +55,18 @@ int getBufferSizeFrom(int sock); * thread safe */ ssize_t timeout_recv(int fd,void * buf,size_t n,int timeout); -/* +/** * recieve data to buf until all bytes. * thread safe */ ssize_t recv_until_byte(int fd,void * buf, size_t n,int timeout); +/** + * find sockaddr by hostname + * it perform like `gethostbyname` + * hostname could not be greater than _SC_HOST_NAME_MAX. + * return 0 on success, otherwise return ecode. + * ecode can be converted to string by `gai_strerror`. +*/ +int getsockaddrbyname(int domain,int type, int protocol, const char * hostname_str, struct sockaddr * retaddr); #endif \ No newline at end of file