2013-06-14 2 views
0

У меня большая проблема. Предположим, что у нас есть текстовый файл (с именем file_config.txt) такой нас это:Ошибка подключения к серверу в файле

192.168.1.4 65000 
www.google.com 80 

Они два сервера.

У меня есть сервер, который с нами этот сервер таким образом:

int main(int argc, char *argv[]){ 

...; 

if ((f = fopen(file_name,"r"))!=NULL) { /* file is present */ 

     /* I send the file to the client */ 

}else{ /* file isn't present so I have to contact the server in the txt file */ 

     config = fopen(file_config,"r"); 

     line = 0; 

     flag = 0; 

     while (fgets(file_line,MAXLINE,config)!=NULL) { 

         line ++; 

         r = sscanf(file_line,"%s %s",server,port); 

         flag = Client(server,port,rbuffer,socket); 

         if (flag == 1) { 

          break; 
         } 
     } 

     fclose(config); 

     if (flag == 0) { 
      Send(s,errore,strlen(errore)); 
      break; 
     }     

} 

} 

А вот функция Клиент:

int Client(char *server, char *porta,char *comando, int file_descriptor){ 

    const int MAXBUF = 7; 
    const int MAX = 70; 
    char termine[] = "QUIT\r\n"; 
    char indirizzo_IP[24]; 
    struct in_addr indirizzo_server; 
    struct sockaddr_in indirizzo_remoto; 
    struct hostent *h; 
    uint16_t porta_server; 
    char resoconto[MAX]; 
    char *buffer; 
    int s; 
    int i; 
    int flag; 
    long bytes; 
    int n; 

    /* porta del server */ 

    if(sscanf(porta,"%" SCNu16,&porta_server)!=1){ 

     printf("Errore durante la lettura della porta dal file\n"); 

     return 0; /* equivale a file non trovato */ 
    } 

    /* verifico se server è un indirizzo IP oppure se è un CNAME */ 

    flag = 0; 

    for (i=0; i<strlen(server); i++) { 
     if ((isalpha(server[i]))==0) { 
      flag = 1; 
     } 
    } 

    /* indirizzo Server */ 

    if(flag == 0){ /* server è un indirizzo IP */ 

     inet_aton(server,&indirizzo_server); 

     /* allocazione della struttura indirizzo_remoto */ 

     memset((char *)&indirizzo_remoto,0,sizeof(struct sockaddr_in)); 

     /* preparazione indirizzo del server */ 

     indirizzo_remoto.sin_family = AF_INET; 

     indirizzo_remoto.sin_port = htons(porta_server); /* porta su cui è in ascolto il server */ 

     indirizzo_remoto.sin_addr = indirizzo_server; /* indirizzo al quale il server esegue : indirizzo_remoto.sin_addr.s_addr = inet_addr("192.168.1.4"); */ 


    }else{ /* server è un Canonical NAME */ 

     h = gethostbyname(server); 

     if(h == NULL){ 
      printf("Errore"); 
      return 0; /* passo al server successivo */ 
     } 

     inet_aton(h->h_addr_list[0],&indirizzo_server); 

     /* allocazione della struttura indirizzo_remoto */ 

     memset((char *)&indirizzo_remoto,0,sizeof(struct sockaddr_in)); 

     /* preparazione indirizzo del server */ 

     indirizzo_remoto.sin_family = AF_INET; 

     indirizzo_remoto.sin_port = htons(porta_server); /* porta su cui è in ascolto il server */ 

     indirizzo_remoto.sin_addr = indirizzo_server; /* indirizzo al quale il server esegue : indirizzo_remoto.sin_addr.s_addr = inet_addr("192.168.1.4"); */ 

     printf("Il nome '%s' ha indirizzo IP '%s' e porta '%d'\n",server,inet_ntoa(indirizzo_remoto.sin_addr),ntohs(indirizzo_remoto.sin_port)); 
    } 


    /* creazione del socket */ 

    s = Socket(); 

    /* connessione con il socket remoto - quello sul server */ 

    if((connect(s,(struct sockaddr *) &indirizzo_remoto,sizeof(indirizzo_remoto)))==-1){ 
     Stampa_errore("connect() errore"); 
    } 

    printf("connect() fatta"); 

    /* Invio al server il comando */ 

    Send(s,comando,strlen(comando)); 

    /* Ricevo risposta dal server */ 

    Recv(s,resoconto,MAXBUF); 

    if (strcmp(resoconto,"+OK\r\n")==0) { /* il server in questine non ha il file */ 

     /* Aspetto di ricevere la dimensione del file */ 

     n = recv(s,&bytes,sizeof(bytes),0); /* USARE LA FUNZIONE DEL PROFESSORE */ 

     printf("recv: %d - bytes: %ld\n",n,bytes); 

     /*if() { 
      return 0; /* vado alla riga dopo */ 
     //} 

     /* invio al client da dimensione */ 

     send(file_descriptor,&bytes,sizeof(bytes),0); 

     bytes = ntohs(bytes); 

     /* faccio l'allocazione dinamica */ 

     buffer = (char *)malloc(sizeof(char)*bytes); 

     if (buffer==NULL) { 

      printf("Memoria non disponibile per ricevere il file\n"); 
      exit(-1); 

     } 

     read(s,buffer,bytes); /* ATTENZIONE: provare a sostituire con recv */ 

     /* invio il file al client */ 

     Send(file_descriptor,buffer,bytes); 

     /* fare free */ 

     free(buffer); 

     /* invio QUIT\r\n al server */ 

     Send(s,termine,strlen(termine)); 

     /* chiudo il socket */ 

     close(s); 

     return 1; /* = 1 file trovato/= 0 file non trovato */ 

    }else{ 
     printf("Il server non ha compreso il comando\n"); 
     Close(s); 
     printf("Socket chiuso\n"); 
     return 0; /* analogo a file non trovato su questo server */ 

    } 

} 

Это не работает:

Если первый сервер в файле txt есть файл, в котором работает код. Но если у первого сервера нет файла, метод Client останавливается после Socket (Socket - последнее действие, которое идет хорошо).

P.S .:

Я знаю, что я не могу связаться с www.google.com и задать файл с моим собственным протоколом. Но я вставляю его только для проверки правильности разрешения канонического имени.

+0

, где он не работает? каково текущее и ожидаемое поведение? – VoidPointer

+0

Я обновляю вопрос с помощью действия редактирования. Сожалею! – user2467899

+0

У клиента есть комментарий на итальянском языке, если есть такие же проблемы, я их переводил – user2467899

ответ

0

Эта линия:

inet_aton(h->h_addr_list[0],&indirizzo_server); 

неправильно. h_addr_list не является списком строк в формате, который inet_aton ожидает. Это даже не список строк. Это список адресов, готовых для копирования непосредственно в соответствующее поле struct sockaddr_*.

char **h_addr_list в struct hostent следует рассматривать как void **, что это то, что было бы, если бы не был разработан, прежде чем ANSI C дал нам void. Используется общий указатель, потому что gethostby* поддерживает (по крайней мере теоретически) произвольные семейства адресов.

В случае h_addrtype==AF_INET, каждый h_addr_list[n] является указателем на struct in_addr, так что вы можете просто сказать indirizzo_server = *(struct in_addr *)h_addr_list[0]; и все будет хорошо.

Смежные вопросы