PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : gethostbyname, char **h_addr_list enthält int ?!? *verwirrtist*


JeffJohnson
17.05.2006, 11:12
Hallo,

ich bin gerad am rumprobieren mit der gethostbyname lib.
Ich habe nun gethostbyname aufgerufen und das Ergebniss für einen hostnamen in einer hostent struct gespeichert.

Nun will ich die IP auslesen, die wird in einem char **h_addr_list in der struct gespeichert.

Was mich verwirrt ist wenn ich h_addr_list[0][1] ausgeben will, sagt mir der compiler das dort ein INT Wert gespeichert ist?
Wie kann in einem char pointer auf pointer INTs gespeichert sein?
Wie lese ich die ganze IP Adresse aus?
In einer Schleife mithilfe von h_length? Oder gibt es einen besseren Weg?

Danke

Gruß

Fabian


badphantom
17.05.2006, 11:14
Kannst du mal ein Code-Snippet posten?

JeffJohnson
17.05.2006, 12:23
#include <stdlib.h>
#include <stdio.h>
#include <sys/socket.h>
#include <unistd.h> /* close */
#include <netdb.h>
[...]

int sock;
struct hostent *hostbynameresult;
char *addr;
addr="heise.det";
hostbynameresult = gethostbyname(addr);
printf("%d",hostbynameresult->h_addr_list[0][1]);

Jidder
17.05.2006, 12:49
char **h_addr_list ist ein zeiger auf einen zeiger auf einen char. wenn du ihn also 2x derefenzierst ([0] und [1]) dann erhältst du den char. und für die meisten compiler ist ein char bloß ein 8bit großes int. h_addr_list[0][1] enthält vom ersten hostnamen ([0]) den zweiten buchstaben ([1]). Wenn du also an einen string willst, musst du nur printf("%s\n", hostbynameresult->h_addr_list[0]); machen.

TekWarrior
17.05.2006, 14:55
Das liegt daran, dass bestimmte Typen in einer variadischen Funktion (wie z.B. printf()) auf einen anderen bestimmten Typen erweitert werden. char und short werden z.B. zu einem int erweitert. %d erwartet ein signed int, und das Vorzeichenbit, falls char auf deinem System signed ist, wird an die Stelle des Vorzeichenbits eines ints verschoben (sign-extended). Falls char bei dir unsigned ist, kommt es evtl. zu undefined behaviour - dann kann passieren was will ;). Du solltest in Erwägung ziehen, %u statt %d zu benutzen, und deinen Parameter auf unsigned casten.
Es gibt auch die Funktion inet_ntoa() welche dir einen String im Format a.b.c.d liefert ;).

@Jidder:
Das mit der Ausgabe als String geht hier nicht, da hier die einzelnen octets der IP Adresse gespeichert sind ;).

Jidder
17.05.2006, 23:45
Ups. Ja, klar... :mauer: Wieder nicht nachgedacht ;)

JeffJohnson
21.05.2006, 17:18
jetzt versteh ich garnix mehr :o

printf("%u",(unsigned int)(hostbynameresult->h_addr_list));

Gibt mir irgendwelche Zahlen aus die überhaupt nix mit der IP zutun haben.

Und für inet_ntoa müsste ich ja erst ne neue struct in_addr definieren und dort dann den inhalt von hostbynameresult->h_addr_list reinkopieren...

Jidder
21.05.2006, 19:40
Wenn du die IP als 32 Bit Zahl haben willst, geht das so:
printf("%u\n", *(unsigned int*)(hostbynameresult->h_addr_list[0]));
Funktioniert allerdings nur korrekt auf Big Endian Systemen. Für Little Endian Systeme wie dem x86er musst du vorher die Reihenfolge der Bytes umkehren. Lohnt sich vermutlich nicht, angesichts der folgenden alternativen ;)

Wenn du eine IP in der gängigen Darstellung willst, nimm das:
printf("%d.%d.%d.%d\n", (unsigned char)hostbynameresult->h_addr_list[0][0],
(unsigned char)hostbynameresult->h_addr_list[0][1], (unsigned char)hostbynameresult->h_addr_list[0][2],
(unsigned char)hostbynameresult->h_addr_list[0][3]);

Und wenn du auch denkst, dass fertige Funktionen immer noch am besten sind, nimm das hier:
printf("%s\n", inet_ntoa(*(struct in_addr*)(hostbynameresult->h_addr_list[0])));

TekWarrior
21.05.2006, 20:50
Wenn du eine IP in der gängigen Darstellung willst, nimm das:
printf("%d.%d.%d.%d\n", (unsigned char)hostbynameresult->h_addr_list[0][0],
(unsigned char)hostbynameresult->h_addr_list[0][1], (unsigned char)hostbynameresult->h_addr_list[0][2],
(unsigned char)hostbynameresult->h_addr_list[0][3]);


Warum %d und ein unsigned int (Typerweiterungen)? %d ist nur für signed ints, und wenn du ein unsigned int übergibst verursachst du vom Standard her gesehen undefined behaviour ;). Daher %u benutzen.

Jidder
21.05.2006, 21:43
Tja, aber wo bliebe bei %u dann die Spannung? ;)