|
Winsock Tutorial von c-worker.ch (Teil 2: Hostnamen auflösen) Dieses Tutorial stammt von
www.c-worker.ch. Hinweise Falls beim kompilieren
einige "Neudefinition" Fehler kommen entfernt die "#include <winsock2.h>"
Zeile (wurde in diesem Fall schon in windows.h includiert)
1.
Einleitung
Im ersten Tutorial wurde unter anderem gezeigt wie man eine Verbingung zu einem Server aufbaut. Das ganze war jedoch nicht sehr flexibel da wir die IP des Servers in unseren Quellcode reingeschrieben haben. Besser wäre es doch wenn man die IP oder noch besser den Hostnamen als Parameter an das Programm übergeben könnte. Und genau das werden wir hier machen. Der Client vom letzten Tutorial (sock.c) wird hier so erweitert das man als ersten Parameter einen Hostnamen oder eine IP angeben kann, zu welchem dann die Verbindung hergestellt wird.
2. Hostnamen in eine IP auflösen Um einen Hostnamen in eine IP aufzulösen steht die Funktion gethostbyname() zur verfügug: struct hostent FAR * gethostbyname ( -name: ein Hostname für den die IP herausgefunden werden soll Als Rückgabewert liefert die Funktion einen Pointer auf eine HOSTENT Struktur, diese ist folgendermassen definiert: struct hostent {
Dabei interessiert uns nur
h_addr_list, welches eine mit 0 terminierte Liste von IP Adressen ist,
und zwar in Network Byte Order (also kein htonl() nötig). Wir schreiben nun eine eigene
Funktion die all diese Arbeit abnimmt, dabei übernimmt sie als ersten Parameter
einen String (char*) und als zweiten Parameter einen Pointer auf eine SOCKADDR_IN
Strucktur, welche von der Funktion abgefüllt wird (allerdings nur das sin_addr
Feld). Als Rückgabewert liefert sie SOCKET_ERROR bei einem Fehler. long getAddrFromString(char* hostnameOrIp, SOCKADDR_IN* addr)
{
long rc;
unsigned long ip;
HOSTENT* he;
/* Parameter prüfen */
if(hostnameOrIp==NULL || addr==NULL)
return SOCKET_ERROR;
/* eine IP in hostnameOrIp ? */ ip=inet_addr(hostnameOrIp); /* bei einem fehler liefert inet_addr den Rückgabewert INADDR_NONE */
if(ip!=INADDR_NONE)
{
addr->sin_addr.s_addr=ip;
return 0;
}
else
{
/* Hostname in hostnameOrIp auflösen */
he=gethostbyname(hostnameOrIp);
if(he==NULL)
{
return SOCKET_ERROR;
}
else
{
/*die 4 Bytes der IP von he nach addr kopieren */
memcpy(&(addr->sin_addr),he->h_addr_list[0],4);
}
return 0;
}
}
//Prototypen int main(int argc, char** argv)
{
long rc;
SOCKET s;
SOCKADDR_IN addr;
char buf[256];
if(argc<2)
{
printf("Usage: sock <hostname oder ip des servers>\n");
return 1;
}
.....
// Verbinden
Der komplette Quellcode für den neuen Client kann auch hier heruntergeladen werden: sock2.c Um es zu testen muss natürlich wieder zuerst in einer anderen Konsole socksrv gestartet werden. Dann kann sock2 zB folgendermassen aufgerufen werden: sock2 localhost Und localhost sollte erfolgreich in eine IP aufgelöst werden, und die Verbindung zustande kommen. Falls man ein eigenes Netzwerk hat kann man das nun auch richtig übers Netz testen. Man startet socksrv auf einem Rechner (zB mit dem namen machine1) und sock2 auf einem anderen Rechner, als ersten Parameter gibt man sock2 machine1 an, und das ganze sollte eigentlich einwandfrei laufen, vorausgesetzt es ist ein DNS verfügbar der machine1 in eine IP umwandeln kann oder man hat lokal in den entsprechenden Dateien einen Eintrag. Das war es auch schon wieder.
|
||||