Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Externe IP herausfinden

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
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
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
19.09.2006, 19:58 Uhr
virtual
Sexiest Bit alive
(Operator)


Nett aber umständlich: getpeername gibt dir die IP des Gegenübers zurück, übrigens ohne daß da ein Webserver laufen müsste, welcher HTTP kann.
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
19.09.2006, 20:13 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja er will ja die lokale "externe" ip - also die auf die maskiert wird bei nat z.B.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: