Newsgroup: it.comp.lang.c
Titolo: Problema con gethostbyname

Salve,
per sperimentare conla programmazione in rete, ho provato con questo
semplice programmino che data la funzione gethostbyname mi dovrebbe
stampare l'indirizzo dell'host e l'indirizzo IP.
#include <netdb.h>
#include "string.h"
#include "stdio.h"
#include "stdlib.h"
#include <sys/socket.h>
#include <arpa/inet.h>
int main(int argc, char *argv[])
{
 struct hostent *host;
int i=0;
int j=0;
#ifdef LINUX
printf("\n Stai eseguendo il programma su sistema operativo Linux \n");
#endif
host=gethostbyname(argv[1]);
printf("\n hostname \n");
printf("%s ",host->h_name);
for (j=0;j<host->h_length;j++)
printf("%d : ",host->h_addr[j]);
printf("\n Indirizzi :\n");
while((host->h_addr_list[i])!=NULL)
{
printf("%s ",inet_ntoa(*(struct in_addr *)host->h_addr_list[i]));
printf("\n");
i++;
}
}
Ora, il problema sta nel ciclo
for (j=0;j<host->h_length;j++)
printf("%d : ",host->h_addr[j]);
che mi stampa correttamente gli ultimi due valori dell'indirizzo IP
dell'host, mentre invece i primi due me li da come complemento a 256
Mandando in esecuzione il programma ecco l'output
 Stai eseguendo il programma su sistema operativo Linux
 hostname
www.teachingonline.it
 -64 : -88 : 1 : 102 :  // output del ciclo di for
 Indirizzi : // output del ciclo while
192.168.1.102
Francesco
-- 
      Teaching OnLine 
Corsi online di programmazione
Php, Asp, C, C++, Visual Basic, Delphi
Linux Shell Programming
------------------------------------
http://www.teachingonline.it

 
Perché host->h_addr e` un puntatore a char ed i valori 192 e 168 sono 
numeri negativi se rappresentati in un signed char.
Ciao
Giovanni
-- 
   A computer is like an air conditioner,
   it stops working when you open Windows.
   Registered Linux user #337974  < 
http://giovanni.homelinux.net/
 >

 numeri negativi se rappresentati in un signed char.
E quindi, non esiste un modo per visualizzarli correttamente?


 E quindi, non esiste un modo per visualizzarli correttamente?
Puoi usare %u come specifica di formato
	printf("%u : ",host->h_addr[j]);
oppure mettere un cast
	printf("%d : ",  (unsigned)host->h_addr[j]);


 	printf("%d : ",  (unsigned)host->h_addr[j]);
Ho trovato che la soluzione funzionante è
printf("%d : ",  (unsigned char)host->h_addr[j]);
ma perchè?
h_addr non un un puntatore a carattere, cioè una stringa?
Francesco

Lampa Dario ha scritto:

il problema, come qualcuno aveva anticipato, è che per un signed char
i primi due valori del tuo array erano negativi (perchè superiori a
127). Se fai un cast in unsigned char invece, i valori che può
assumere la variabile vanno da 0 a 255, tutti positivi, con il
risultato corretto.
Spero di essermi fatto capire...

> Spero di essermi fatto capire...
Forse sono io che non mi faccio capire. Data la struttura di hostent
struct hostent{
  char  *h_name;         /* official (cannonical) name of host               */
  char **h_aliases;      /* pointer to array of pointers of alias names      */
  int    h_addrtype;     /* host address type: AF_INET                       */
  int    h_length;       /* length of address: 4                             */
  char **h_addr_list;    /* pointer to array of pointers with IPv4 addresses */
};
e
#define h_addr  h_addr_list[0]  /* first address in list                     */
si presume, dalla definizione, che h_addr sia una normale stringa. Da
nessuna parte leggo che gli elementi di h_addr siano unsigned_char. Il
problema che mi ponevo era: come facevo a saperlo? O meglio: c'è qualche
fonte da cui attingere, una convenzione non scritta, o c'era un modo per
capirlo leggendo la struttura di hostent?
Francesco


E` per il modo in cui arriva il dato in rete.  Dato che e` in formato 
'network' (BIG ENDIAN) per una corretta conversione i 32 bits sono visti 
come 4 chars (non una stringa!).  Per questo la lista e` un array di 
puntatori ad array di 4 caratteri.  In realta` potresti considerare la 
lista come un array di puntatori a strutture di tipo 'struct in_addr'.
