000
19.09.2006, 19:26 Uhr
Tron
|
Moin,
da ich häufig auf die Frage nach der externen IP gestoßen bin, habe ich da mal was zu gemacht. Die src sollte bei all den Kommentaren auch für Anfänger selbst erkläred sein. Ist zwar für Win. sollte aber auch leicht an andere BS und Sprachen angepasst werden können.
Benutze dafür folgenden Server: http://checkip.dyndns.org/ - ACHTUNG: Es werden nur einige Anfragen in einem Zeitraum von 10 min erlaubt, danach wird man eine Zeit lang gesperrt! Also nicht übertreiben.
Falls ich hier im falschen Forum poste, bitte verschieben!
C++: |
/* Dateiname: getexip.c
Es wird ein GET request via http an einen Webserver gesendet und das Ergebnis auf der Konsole ausgegeben. Hier die externe IP die aus der empfangenen HTML-Seite extrahiert wird. Folgende Server geben Auskunft: www.heise.de/ip/default.shtml
http://checkip.dyndns.org/ - ACHTUNG: Es werden nur einige Anfragen in einem Zeitraum von 10 min erlaubt, danach wird man eine Zeit lang gesperrt! www.dyndns.com/services/dns/dyndns/faq.html Hier wird der Server von checkip.dyndns.org genutzt, da sich die IP hier leicht extrahieren läßt. */
//------------------------------------------------------------------------------ #include <stdio.h> #include <errno.h> #include <winsock2.h> #include <io.h> // write
// http requests werden normal auf Port 80 angenommen. #define HTTP_PORT 80
//------------------------------------------------------------------------------ int main( int argc, char **argv) { struct sockaddr_in server; struct hostent *host; int sock = 0; char buffer[1024]; char *teil_str = ""; char *ip = ""; char *servname = "checkip.dyndns.org"; char *site = "/index.html"; int count = 0; unsigned int iplen = 0;
/** Die Windows Socket WSAStartup Funktion initialisiert die WS2_32.DLL für den Gebrauch durch einen Prozess. Das Makro MAKEWORD übergibt die Versionnummer der verwendeten Socketversion, wsa ist ein Pointer auf WSADATA wird hier nicht benötigt.
WSAStartup gibt bei einem Fehler einen Wert ungleich NULL zurück. Dieser Fehlercode kann mit WSAGetLastError abgefragt werden. */ WSADATA wsa; if(WSAStartup(MAKEWORD(2, 0),&wsa)!=0) { fprintf(stderr, "Fehler: %ld bei Initialisierung der Ws2_32.dll", WSAGetLastError()); // WSACleanup - Socket (WS2_32.dll) nach Gebrauch abräumen. WSACleanup(); return 1; } // ende if // Socket erzeugen. sock = socket(PF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("Fehler beim anlegen des Socket"); closesocket(sock); WSACleanup(); // s.o. return 1; } // ende if // Socketadresse erzeugen // besteht aus Typ, IP-Adresse und Portnummer. // Die ersten n Bytes von server auf den Wert 0 setzen. memset(&server, 0, sizeof (server)); // Servernamen nach IP-Adresse. host = gethostbyname(servname); if (NULL == host) { fprintf(stderr, "Unbekannter Server: %s\n", servname); closesocket(sock); WSACleanup(); // s.o. return 1; } // ende if // kopiere den Inhalt von host->h_addr nach server.sin_addr. memcpy((char *)&server.sin_addr, host->h_addr, host->h_length); // Protokol und Port. server.sin_family = AF_INET; server.sin_port = htons(HTTP_PORT); // Baue die Verbindung zum Server auf. if (connect(sock, (struct sockaddr*)&server, sizeof( server)) != 0) { perror("Fehler beim verbinden mit Server"); closesocket(sock); WSACleanup(); // s.o. return 1; } // ende if // Erzeuge und sende den http GET request. // RFC 2616 Hypertext Transfer Protocol -- HTTP/1.1 sprintf(buffer, "GET %s HTTP/1.1\nHost: %s\r\n\r\n", site, servname); send( sock, buffer, strlen( buffer), 0); printf("Externe IP-Adresse wurde ermittelt von %s\n",servname); // Hole die Serverantwort. while(count != SOCKET_ERROR ) { count = recv(sock, buffer, sizeof(buffer), 0); if (count == 0 ) { printf("Verbindung beendet.\n"); break; } // ende if // Ausgabe des HTML Headers und der angeforderten Seite. // auskommentiert da nur für Test. //write(1, buffer, count); } // ende while if (count == SOCKET_ERROR ) { printf("Fehler: %ld beim Empfang!\n", WSAGetLastError()); closesocket(sock); WSACleanup(); // s.o. return 1; } // ende if // Ab hier wird die empfangende HTML-Seite zerlegt. // Der Einfachheit halber habe ich mir die Content-Length vorher // im HTML-Header angesehen. Muss sonst extrahiert werden. // Content-Length: 106 // Wert von Content-Length für buffer-Element verwenden und '\0' anfügen. buffer[106] = '\0'; // Extrahieren der IP aus der HTML-Seite. // Letztes Vorkommen eines Leerzeichens ermitteln (hier vor der IP). teil_str = strrchr(buffer,' '); // Ermitteln an welcher Stelle der Zeichenkette <\body> enthalten ist. // Dies ergibt die Länge der Zeichenkette für die IP. // Das Leerzeichen vor der IP wird mitgezählt! iplen = strcspn(teil_str,"<\body>"); // Anzahl (iplen) Zeichen von Zeichenkette test nach Zeichenkette ip kopieren. strncpy(ip, teil_str,iplen); // '\0' an Zeichenkette ip anfügen. ip[iplen] = '\0'; printf("Externe IP-Adresse ist%s\n",ip); // Schließe Socket. closesocket(sock); // WSACleanup - Socket ( WS2_32.dll) nach Gebrauch abräumen. WSACleanup(); return 0; }
|
Verbesserungsvorschläge sind jederzeit willkommen. Viel Spaß damit.
Gruß Tron |