Plattformübergreifende Steckdosen

Lesezeit: 5 Minuten

Benutzeravatar von ForceBru
ForceBru

Ich weiß, Windows verwendet keine UNIX-Sockets, während Mac OS dies tut. Bis zu diesem Zeitpunkt war meine Software plattformübergreifend ohne Codeänderungen. Aber jetzt möchte ich, dass es etwas Netzwerkkommunikation macht. Ich kenne POSIX-Sockets, aber ich weiß nichts über die von Windows. Das Ziel ist die Implementierung eines einfachen plattformübergreifenden Socket-Servers.

Könnten Sie mir bitte die Unterschiede zwischen POSIX- und Winsock-Sockets erklären und wie ich beim Schreiben von plattformübergreifendem Netzwerkcode vorgehen kann?

  • Es geht über reine Sockets hinaus, aber ich finde 0mq (ZeroMq) sehr interessant.

    – naja

    19. Januar 2015 um 15:24 Uhr

  • Normalerweise nehme ich das POSIX-Programm und kompiliere es mit gcc unter Cygwin und verteile es dann so 😉 Zusätzlicher Bonus: Es macht mein Leben unter Windows viel einfacher.

    – Karl Kubat

    19. Januar 2015 um 15:25 Uhr


  • Leider (?) Fragen, die Empfehlungen stellen, sind hier ausdrücklich nicht zum Thema. Eine Lösung besteht jedoch darin, entweder Cygwin (wenn Sie eine andere Unix-ähnliche Infrastruktur benötigen) oder Mingw (wenn Sie keine “gefälschte Unix” -Umgebung für Ihr Programm benötigen, nur die C-Bibliotheken / APIs sind ausreichend) zum direkten Erstellen zu verwenden Ihren Unix/Linux-Quellcode.

    – Hyde

    19. Januar 2015 um 15:28 Uhr


  • stackoverflow.com/questions/2952733/…

    – Matte

    19. Januar 2015 um 15:30 Uhr

  • Dies ist die Art von Frage, die sehr nützlich war, tut mir leid, dass sie geschlossen wurde

    – Harald Scheirich

    22. Oktober 2019 um 16:47 Uhr

Benutzeravatar von GoBusto
GoBusto

WinSock versus POSIX-Sockets

WinSock und Posix Steckdosen funktionieren auf ähnliche Weise – hauptsächlich weil Windows-Sockets basierten ursprünglich auf Code von BSD:

Obwohl diese proprietären BSD-Derivate in den 1990er Jahren weitgehend durch die Systeme UNIX System V Release 4 und OSF / 1 ersetzt wurden (die beide BSD-Code enthielten und die Grundlage anderer moderner Unix-Systeme bilden), boten spätere BSD-Versionen eine Grundlage für mehrere offene Source-Entwicklungsprojekte, zB FreeBSD, OpenBSD, NetBSD, Darwin oder PC-BSD, die im Gange sind. Diese wiederum sind ganz oder teilweise in moderne proprietäre Betriebssysteme eingeflossen, z den TCP/IP-Netzwerkcode (nur IPv4) in Microsoft Windows und die meisten der Grundlagen von Apples OS X und iOS.

Es gibt jedoch ein paar Dinge, die Sie anders handhaben müssen, wenn Sie “socket-library-agnostic” Code schreiben möchten.

Hinweis: Die folgenden Beispiele wurden mit Code::Blocks und GCC unter Windows XP (x86) und Debian Testing (AMD64) getestet.

Die Header- und lib-Dateien sind unterschiedlich

Je nachdem, ob Sie Windows verwenden oder nicht, müssen Sie unterschiedliche Header-Dateien einfügen:

#ifdef _WIN32
  /* See http://stackoverflow.com/questions/12765743/getaddrinfo-on-win32 */
  #ifndef _WIN32_WINNT
    #define _WIN32_WINNT 0x0501  /* Windows XP. */
  #endif
  #include <winsock2.h>
  #include <Ws2tcpip.h>
#else
  /* Assume that any non-Windows platform uses POSIX-style sockets instead. */
  #include <sys/socket.h>
  #include <arpa/inet.h>
  #include <netdb.h>  /* Needed for getaddrinfo() and freeaddrinfo() */
  #include <unistd.h> /* Needed for close() */
#endif

Sie müssen auch mit verknüpfen Ws2_32 lib-Datei unter Windows.

WinSock erfordert Initialisierung und Bereinigung.

Die folgenden Funktionen veranschaulichen, wie Sie WinSock v1.1 initialisieren und anschließend bereinigen können:

int sockInit(void)
{
  #ifdef _WIN32
    WSADATA wsa_data;
    return WSAStartup(MAKEWORD(1,1), &wsa_data);
  #else
    return 0;
  #endif
}

int sockQuit(void)
{
  #ifdef _WIN32
    return WSACleanup();
  #else
    return 0;
  #endif
}

Socket-Handles sind auf Winsock UNSIGNED

Für Sockets im POSIX-Stil können Sie einfach verwenden int zum Aufbewahren eines Sockelgriffs. Ungültige Sockets werden durch einen negativen Wert angezeigt.

Jedoch, WinSock-Sockets sind UNSIGNED Integermit einer speziellen Konstante (INVALID_SOCKET) anstelle von negativen Zahlen verwendet.

Sie können die Unterschiede durch abstrahieren typedefing SOCKET als int auf POSIX und das Verstecken der Überprüfung “gültiger Socket” hinter einem Makro oder einer Funktion.

Steckdosen werden unterschiedlich geschlossen

Die folgende Funktion veranschaulicht die Unterschiede:

/* Note: For POSIX, typedef SOCKET as an int. */

int sockClose(SOCKET sock)
{

  int status = 0;

  #ifdef _WIN32
    status = shutdown(sock, SD_BOTH);
    if (status == 0) { status = closesocket(sock); }
  #else
    status = shutdown(sock, SHUT_RDWR);
    if (status == 0) { status = close(sock); }
  #endif

  return status;

}

Im Allgemeinen sind sie sich jedoch ziemlich ähnlich.

Wenn Sie sich an “gängige” Funktionen halten (wie z send() oder recv()) und vermeiden Sie plattformspezifische Dinge (wie z WSAWaitForMultipleEvents()) Dann sollte es dir gut gehen.

  • Ein weiterer Unterschied besteht darin, dass Windows WinSock funktioniert nicht gut mit Basic read() und write() Aufrufe, mit denen POSIX-Sockets problemlos funktionieren. Zum Beispiel anrufen write( socket, buffer, bytes ) auf einem WinSock kann zwar fehlschlagen send( socket, buffer, bytes, 0 ) auf der exakt gleichen Buchse funktioniert einwandfrei.

    – Andreas Henle

    21. Dezember 2016 um 11:20 Uhr

  • Warum sagen Sie dem OP, dass es eine Verbindung zu Winsock 2 herstellen soll, und warum sagen Sie ihm, wie es Winsock 1-Sockets bereinigen soll?

    – Stapelhaus

    20. April 2018 um 14:24 Uhr

  • @rstackhouse Sie bereinigen es, indem Sie auf upgraden

    Benutzer11877195

    3. Dezember 2019 um 12:31 Uhr

  • Wenn ich dies verwende, erhalte ich einen Fehler: error C4996: 'inet_addr': Use inet_pton() or InetPton() instead or define _WINSOCK_DEPRECATED_NO_WARNINGS to disable deprecated API warnings. Vielleicht sollte diese Antwort aktualisiert werden?

    – sergiol

    13. September um 15:53 ​​Uhr

Benutzeravatar von Alexander Saprykin
Alexander Saprikin

Kann ich auch empfehlen plibsys Bibliothek: funktioniert sowohl auf Windows- als auch auf UNIX-Systemen (siehe die vollständige Liste auf der Projektseite) mit verschiedenen Compilern. Unterstützt IPv4 und IPv6. Es hat die Tests, wo Sie die Anwendungsbeispiele sehen können. Die Bibliothek selbst ist leicht und tragbar.

Benutzeravatar von GNSL
GNSL

Es gibt viele Bibliotheken und Toolkits, die plattformübergreifende Sockets unterstützen, je nachdem, was Sie tun, können Sie verwenden (um nur einige zu nennen):

  • openssl
  • Apache portable Laufzeitumgebung
  • libtcl

Wenn Sie nicht von einer externen Bibliothek abhängig sein möchten, haben alle oben genannten Pakete ziemlich freizügige Lizenzen, sodass Sie ihren Code als Referenz verwenden können.

Die regulären Sockets (die in der AF_INET-Adressfamilie), die Sie zum Erstellen eines Socket-Servers benötigen, werden auf allen Plattformen gleichermaßen unterstützt.

Verwechseln Sie sie nicht mit Unix-Sockets (die in der AF_UNIX-Adressfamilie) – solche Sockets sind sehr spezifisch für eine Unix-Welt und werden für sehr spezifische Ziele verwendet. Sie würden sie niemals für eine einfache Socket-Server-Anwendung benötigen.

1410580cookie-checkPlattformübergreifende Steckdosen

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy