add getsockaddrbyname
This commit is contained in:
		
							parent
							
								
									eae3af86fb
								
							
						
					
					
						commit
						3e4a5ac1db
					
				
					 4 changed files with 61 additions and 9 deletions
				
			
		
							
								
								
									
										21
									
								
								client.c
									
										
									
									
									
								
							
							
						
						
									
										21
									
								
								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){
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										6
									
								
								server.c
									
										
									
									
									
								
							
							
						
						
									
										6
									
								
								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){
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,7 +5,8 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include <unistd.h>
 | 
			
		||||
#include <poll.h>
 | 
			
		||||
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
#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;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			@ -5,6 +5,7 @@
 | 
			
		|||
#include <sys/socket.h>
 | 
			
		||||
#include <netinet/in.h>
 | 
			
		||||
#include <arpa/inet.h>
 | 
			
		||||
#include <netdb.h>
 | 
			
		||||
 | 
			
		||||
#ifdef USE_SENDFILE
 | 
			
		||||
#include <sys/sendfile.h>
 | 
			
		||||
| 
						 | 
				
			
			@ -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
 | 
			
		||||
		Loading…
	
	Add table
		
		Reference in a new issue