Cross-piattaforma socket

So, Windows non utilizza socket UNIX, mentre Mac OS fa. Fino a questo punto il mio software è multi-piattaforma, senza alcuna modifica del codice. Ma ora voglio fare qualche comunicazione di rete. So che su POSIX prese, ma io non so nulla su Windows’ quelli. L’obiettivo è quello di implementare un semplice cross-piattaforma server socket.

Potrebbe, per favore, mi spieghi le differenze tra POSIX e Winsock prese e come posso andare su scrittura cross platform codice di rete?

  • Va al di là della pura prese, ma trovo 0mq (ZeroMq) molto interessante.
  • Quello che faccio di solito, è di prendere il POSIX programma e compilarlo con gcc sotto Cygwin, quindi distribuire così 😉 un bonus Aggiuntivo di: rende la mia vita su Windows molto più facile.
  • Purtroppo(?) domande che chiedono consigli sono esplicitamente off topic qui. Tuttavia, una soluzione è quella di utilizzare Cygwin (se avete bisogno di altri Unix-like, infrastrutture) o Mingw (se non hai bisogno di un “falso unix” ambiente per il programma, solo le librerie C/Api sono abbastanza) per costruire direttamente in sistemi Unix/Linux il codice sorgente.
  • stackoverflow.com/questions/2952733/…
  • La lettura di msdn.microsoft.com/en-us/library/windows/desktop/… sembra semplice di applicazioni client/server deve essere facilmente trasportabile, cioè si può ottenere via con un paio definisce per soddisfare le differenze, ma essenzialmente una fonte comune. EDIT: vedo che @Mat collegato a una domanda che aveva un simile accettato di rispondere.
InformationsquelleAutor ForceBru | 2015-01-19

 

4 Replies
  1. 63

    WinSock contro POSIX Prese

    WinSock e POSIX prese di lavorare in un modo simile, principalmente perché Windows sockets sono stati originariamente basato sul codice di BSD:

    Anche se questi proprietari BSD derivati sono stati in gran parte sostituiti da UNIX System V Release 4 e OSF/1 sistemi nel 1990 (entrambi incorporati codice BSD e sono alla base dei moderni sistemi Unix), poi BSD versioni fornite base per diversi open source progetti di sviluppo, ad esempio, FreeBSD, OpenBSD, NetBSD, Darwin o PC-BSD, che sono in corso. Questi, a loro volta, sono state incorporate in tutto o in parte nei moderni sistemi operativi proprietari, ad esempio il TCP/IP (solo IPv4) codice di rete in Microsoft Windows e la maggior parte di fondazione di Apple OS X e iOS.

    Tuttavia, ci sono un paio di cose di cui avrete bisogno per gestire in modo diverso, se si desidera scrivere “socket-biblioteca-agnostico” codice.

    Nota: Gli esempi seguenti sono stati testati utilizzando Code::Blocks e GCC su Windows XP (x86) e Debian Testing (AMD64).

    L’intestazione e file lib sono diversi

    È necessario includere diversi file di intestazione a seconda se si sta utilizzando Windows o non:

    #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

    Avrete anche bisogno di collegamento con Ws2_32 lib file su Windows.

    WinSock richiede l’inizializzazione e la pulizia.

    Le funzioni di seguito viene illustrato come è possibile inizializzare WinSock v1.1 e pulire dopo:

    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
    }

    Handle di Socket sono FIRMATI su Winsock

    Per POSIX stile prese, si può semplicemente utilizzare int per memorizzare un handle di socket. Non valido per le prese indicato da un valore negativo.

    Tuttavia, WinSock prese sono numeri interi senza segno, con una speciale costante (INVALID_SOCKET) utilizzato invece di numeri negativi.

    È possibile abstract differenze typedefing PRESA come int su sistemi POSIX e nascondere il “socket valido” check dietro una macro o funzione.

    Prese sono chiuso in modo diverso

    La funzione riportata di seguito illustra le differenze:

    /* 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;
    
    }

    In linea generale, tuttavia, sono abbastanza simili.

    Se si bastone “comune” di funzioni (come send() o recv()) e di evitare specifici per la piattaforma di roba (come WSAWaitForMultipleEvents()) quindi dovresti essere a posto.

    • Un’altra differenza è che Windows’ WinSock non funziona bene con la base read() e write() chiamate POSIX prese lavorano solo con il bene. Ad esempio, la chiamata write( socket, buffer, bytes ) su un WinSock può fallire, mentre send( socket, buffer, bytes, 0 ) la stessa presa funziona bene.
    • Perché raccontare la OP di link contro Winsock 2 e raccontare loro come pulire Winsock 1 prese?
  2. 3

    Posso anche suggerire il plibsys biblioteca: funziona sia su sistemi Windows e UNIX (vedi l’elenco completo nella pagina del progetto) con i vari compilatori. Supporta IPv4 e IPv6. Ha le prove dove è possibile vedere l’utilizzo di esempi. La biblioteca è leggero e portatile.

  3. 2

    Ci sono molte librerie e strumenti che supportano il cross piattaforma socket, a seconda di che cosa si sta facendo, è possibile utilizzare (per citarne alcuni):

    • openssl
    • apache portable runtime
    • libtcl

    Se non si desidera avere una dipendenza da una libreria esterna, tutti i pacchetti di cui sopra sono abbastanza licenze permissive, in modo che è possibile utilizzare il loro codice come riferimento.

  4. 1

    Normali prese (quelle in AF_INET indirizzo di famiglia) che è necessario costruire un socket server sono ugualmente supportato su tutte le piattaforme.

    Non confondere con socket Unix (quelli in AF_UNIX indirizzo famiglia) – tali prese sono altamente specifico per un mondo Unix, e sono utilizzati per un altamente specifici obiettivi. Non avrebbe mai bisogno di loro per una presa semplice applicazione server.

Lascia un commento