Sockets mit WinAPI
Socket erstellen
Jetzt sind wir mittlerweile schon in Kapitel vier und haben immer noch kein Socket in unseren Händen. Dabei habe ich doch versprochen, dass Socketprogrammierung mit der WinAPI recht schnell geht. Dann holen wir uns doch gleich mal ein Socket. Der Befehl dazu lautet auch selbst Socket. Jetzt müssen wir Windows mitteilen, was wir eigentlich mit dem Socket anstellen wollen. Dazu übergeben wir 3 Parameter und Windows sucht sich dann den am meisten passenden Sockettyp dazu aus. Die Parameter sind:
- Adressfamilie
- Sockettyp
- Protokollart
Alle 3 Parameter sind 32-bit-Werte (Integer) und entsprechende Konstanten sind schon vordefiniert.
Machen wir es kurz: Unsere Adressfamilie ist das Internet mit IPv4 (andere Adressfamilien wären noch IPX, Unix, Apple, ECMA, …, und auch IPv6).
Beim Sockettyp müssen wir aufpassen. Dazu vielleicht doch noch zwei, drei Sätze. Der Unterschied zwischen UDP und TCP spiegelt sich schon im Sockettyp wieder. Es gibt das Streamsocket. Dieses ist hervorragend für TCP geeignet, da es, wie das TCP auch verlangt, eine Verbindung zu einem anderen Streamsocket aufbauen kann. Und es hält die Informationen und Möglichkeiten (Packetzähler, Nachricht noch mal senden) bereit, die der TCP-Header benötigt. Im Gegensatz dazu (also für UDP) gibt es das Datagrammsocket. Dieses ist ein Verbindungsloses Socket. Die Informationen werden ins Netz hinausgelassen ohne auf Rückantworten oder ähnliches zu warten.
Der dritte Parameter ist dann, wie gesagt, die Protokollart, in unserem Fall TCP oder UDP. Unter Delphi sieht es dann also folgendermaßen aus:
function createSocket_TCP:TSocket; begin result := socket(AF_INET, SOCK_STREAM, IPProto_TCP); if result = INVALID_SOCKET then HandleError; end;
Das war’s schon. Fertig ist unser Streamsocket. Jetzt können wir (schon fast) TCP-Pakete verschicken. Der Ergebnistyp TSocket unser Funktion entspricht dem SocketHandle und ist ein 32-bit Integer. (Für IPv6 würde die Adressfamilie AF_INET6 = 23 sein.)
Wenn Windows aus den drei Parametern kein Socket bilden kann oder sonst ein Fehler auftritt (WSAStartUp nicht aufgerufen, etc.) liefert die Funktion Socket den Wert INVALID_SOCKET zurück. (hier ist es einmal nicht SOCKET_ERROR). Die Verfahrensweise in HandleError kann wie in Kapitel 3 erfolgen (WSAGetLastError usw.).
Für ein Datagrammsocket sähe die Funktion folgendermaßen aus:
function createSocket_UDP: TSocket; begin result := socket(AF_INET, SOCK_DGRAM, IPProto_UDP); if result = INVALID_SOCKET then HandleError; end;
Damit haben wir unser Socket. Schauen wir mal im nächsten Kapitel, ob wir schon was versenden können.
Ein Gedanke zu „Sockets mit WinAPI“
Kommentare sind geschlossen.
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.