0

我有一个大问题。让我们假设我们有一个 txt 文件(名为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 文件中的第一台服务器具有该文件,则代码有效。但是,如果第一个服务器没有文件,则客户端方法在 Socket 之后停止(Socket 是最后一个正常的操作)。

PS:

我知道我无法联系 www.google.com 并使用我自己的协议询问文件。但我插入它只是为了查看规范名称的解析是否正常工作。

4

1 回答 1

0

这一行:

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

是错的。h_addr_list不是inet_aton预期格式的字符串列表。它甚至根本不是一个字符串列表。它是一个地址列表,可以直接复制到struct sockaddr_*.

char **h_addr_listinstruct hostent应该被视为void **,如果它在 ANSI C 给我们之前没有被设计的话,这就是它的样子void。使用通用指针是因为gethostby*支持(至少理论上)任意地址族。

在 的情况下h_addrtype==AF_INET, eachh_addr_list[n]是指向 a 的指针struct in_addr,所以你可以说indirizzo_server = *(struct in_addr *)h_addr_list[0];一切都会好起来的。

于 2013-06-14T21:45:45.597 回答