Home » Tutorials » Netzwerk und Internet » Sockets mit WinAPI

Sockets mit WinAPI

Informationen über Socketverbindung bekommen

Manchmal kann es auch recht spannend sein, Informationen über sein Socket und dessen mögliche Verbindung zu bekommen. Zum Beispiel, wenn man sich von Windows eine Portnummer hat geben lassen, kann man diese auch recht einfach abfragen. Oder wir wollen einfach mal wissen, mit was für einem Socket unser Stream-Socket verbunden ist. Und hin und wieder möchte mal jemand die IP, des eigenen Rechners wissen.
Dazu stelle ich hier mal 3 Funktionen vor (für IPv4; diese sind teilweise für IPv6 nicht mehr zu verwenden und durch andere Funktionen zu ersetzen).

Informationen zum eigenen Socket

Die Funktion dazu ist getsockname und besitzt alt bekannte Parameter:

GetSockName(FSocket: TSocket;
            var SockAddr: TSockAddrIn;
            var AddrLen: Integer);

Ich denke, dazu ist nach meinen bisherigen Ausführungen auch nix weiter zu sagen. Wir bekommen genau die Informationen die wir über bind geliefert haben. Und falls wir unser Socket an Port 0 binden wollten (die Wahl also Windows überlassen haben; oder eben bind nicht direkt aufgerufen haben), dann erfahren wir so unseren Port des Sockets. Die Adresse ist demnach auch nicht unsere IP-Adresse des Rechners, sondern nur die Adresse, an dessen LAN-Verbindung wir unser Socket gebunden haben (oder 0.0.0.0 für alle Verbindungen)
Das Aufschlüsseln der Adresse (Record TSockAddrIn) ist in Kapitel 5 beschrieben.

Informationen zum Remote Socket

Mit denselben Parametern können wir auch getpeername aufrufen und so die Adresse (inkl. Portnummer) einer Socketverbindung, also des anderen Sockets, erfahren.

GetPeerName(FSocket: TSocket;
            var SockAddr: TSockAddrIn;
            var AddrLen: Integer);

Damit bekommen wir die IP-Adresse des anderen Rechners und die dazugehörige Portnummer des anderen Sockets.

Informationen zum eigenen Host

Den Namen unseres Hosts und unsere IP-Adresse unseres Rechners erfahren wir über gethostbyname (oder gethostbyaddr) Als Parameter wird ein Zeiger auf eine Adresse erwartet. Für unseren eigenen Host übergeben wir einfach NIL.
Der Rückgabewert ist ein Zeiger auf ein HostEnt-Record.

function getHostInfo(var IP: string; var HostName: string): Integer;
var HostEnt: PHostEnt;
    Addr: ^PInAddr; //Zeiger auf ein Liste von IP-Adressen
begin
  HostEnt := GetHostbyName(nil);
  if HostEnt = nil then
    Result := WSAgetLastError
  else
  begin
    result := 0;
    HostName := HostEnt^.hname;
    Addr := Pointer(hostEnt^.h_addr_list);
    if (Addr<>nil) and (Addr^<>nil) then
      IP := inet_ntoa(Addr^^)
    else 
      IP:='';

    //um alle IP-Adressen des Rechners zu erfahren
    //muss man den Pointer PHostEnt um 4 Bytes weitersetzen
  end;
end;

So bekommen wir unseren Rechnernamen und unsere IP im Netz. Bitte beachten, dass dies nicht die IP aus dem Internet sein muss, wenn noch ein Router o.ä. zwischengeschaltet ist.
Wir können über diese Funktionen auch Informationen zu anderen Hosts erfahren. Dementsprechend müssen wir statt NIL eine Adresse übergeben.

5 Gedanken zu „Sockets mit WinAPI“

  1. Wo findet sich denn der Link, um die Programmbeispiele herunterzuladen?
    Ich suche jetzt schon eine Weile, finde aber nichts.

  2. Eine weitere – aus meiner Sicht sehr wichtige – Antwort auf die Frage, warum man die Sockets selbst über die Windows API programmieren sollte, wäre noch:

    Ich hatte vor ca. 10 Jahren einen „Chat“ über die Komponenten von Delphi programmiert. Wir haben hier in der Firma einen Linux-Server zu stehen. Da die Leute das lustig fanden, ist der Chat heute fester Bestandteil. Linux bedeutet aber insoweit Probleme, weil ich das Programm emulieren lassen muss. Dafür würde sich theoretisch wine anbieten.
    Der Haken ist aber, dass die Komponenten alle fest in der VCL verankert sind und man mit wine nicht weit kommt. Man braucht also eine virtuelle Maschine mit Windows, um den Server laufen zu lassen. Insoweit erhoffe ich mir, dieses Problem eventuell lösen zu können. Wenn es mir gelingt, mit dieser Anleitung eine eigene Klasse ganz ohne jede VCL erstellen zu können, dann kann ich den Server als Konsolen-Programm erstellen und (endlich) ohne den ganzen Overhead unter wine laufen lassen.

    Falls den Seitenadmin dieser Kommentar stört, kann er ihn gern wieder gelöscht werden. Aber auf der Suche nach Sockets ohne VCL, wäre dies als Fund bei Suchmaschinen schon vor langer Zeit sehr hilfreich für mich gewesen. Suchmaschinen finden aber immer nur den Text, der auf den Seiten tatsächlich irgendwo steht und wenn man nach „nonvcl“ im Zusammenhang mit Sockets unter Delphi sucht, sieht es dünn aus mit den Suchergebnissen.

  3. Hallo, ich kann leider auch deine Programmbeispiele als Datei nicht finden. Sind die nicht mehr verlinkt?

    Ansonsten gutes Tutorial 🙂

Kommentare sind geschlossen.