Domanda

Sto per sviluppare alcune cose relative ai socket in C ++ e vorrei che il software fosse il più portatile possibile tra Windows e Linux fin dall'inizio (renderlo portatile in seguito è complicato.)

Ho guardato diverse librerie, ce n'è una per C ++ da alhem.net e di ovviamente c'è boost :: asio. boost :: asio sembra molto promettente ma sarebbe una dipendenza molto grande per applicazioni così piccole.

Vale anche la pena scrivere le cose da solo o dovrei semplicemente usare una libreria? Se lo faccio da solo, quali sarebbero le principali insidie?

È stato utile?

Soluzione

Winsocks non sono molto compatibili con i socket Posix:

  • In Winsocks un socket è di tipo SOCKET. Su Posix è semplicemente un descrittore di file (int), sul quale è possibile eseguire le normali chiamate read() e write().
  • Non restituiscono errori allo stesso modo.
  • Non supportano alcune opzioni su recv() e send().
  • Devi inizializzare e rendere unitaria la libreria Winsocks con due funzioni speciali.
  • Non credo che tu possa chiudere i socket di Windows con shutdown() o close(). È invece qualcosa come closesocket().

Devono esserci più differenze, ma è quello che posso ricordare in questo momento. Se vuoi la portabilità con Winsocks, avrai una piccola libreria per chiudere un socket, stampare un messaggio di errore e così via.

Probabilmente andrei con boost::asio, personalmente (non l'ho mai usato, però).

Altri suggerimenti

Ho sviluppato alcuni involucri portatili attorno alle prese. Assicurati di non andare nella corsia di merda di non ritorno che è costituito da eventi WinSock2. A parte questo, a mio avviso, le maggiori differenze sono:

  • per avviare la rete in Windows, è necessario chiamare ::WSAStartup(), per spegnerlo in Windows, eseguire ::WSACleanup(); in Linux non fanno nulla
  • close() in Linux è closesocket() in Windows,
  • le dimensioni del buffer predefinite differiscono tra i driver e i sistemi operativi, quindi assicurati di impostarli utilizzando SO_RCVBUF e SO_SNDBUF,
  • SO_REUSEADDR ruba l'indirizzo su Windows, consente frequenti riaperture su Linux; probabilmente vorresti usare questo flag solo in Linux,
  • la creazione di un socket senza blocco utilizza ::ioctlsocket() in Windows, ::fcntl() in Linux,
  • i file di intestazione sono diversi, <sys/socket.h> e gli amici in Linux, <WinSock.h> in Windows,
  • per diventare portatile, il modo più semplice è probabilmente usare ::select() per aspettare che arrivino i dati,
  • fd_set s sono totalmente diversi su Windows / Linux; questo è rilevante solo se è necessario ottimizzare l'inizializzazione di ::recvfrom() s, ad esempio quando si aggiungono / rimuovono socket arbitrari,
  • in Windows, qualsiasi thread sospeso sul socket viene rilasciato con un codice di errore quando il socket viene chiuso, in Linux il thread rimane in attesa. Se il thread sta bloccando il socket con ad esempio ::sendto(), potresti considerare di utilizzare <=> per rilasciare il thread di stallo in Linux.

Tutto il resto di cui abbia mai avuto bisogno è appena uscito da l & # 229; da.

Dai un'occhiata al " Adaptive Communications Environment " (ACE) libreria: (Home page ACE) Offre alcune belle astrazioni e molta flessibilità, tutte raccolte in una libreria portatile che supporta Windows, MacOS e Linux. Ha un po 'di una ripida curva di apprendimento, ma ho ottenuto un ottimo valore da essa.

Quanta roba del socket userai? Ho realizzato diverse app in cui il socket era di livello piuttosto elevato (aperto, leggi, scrivi) e funzionava perfettamente da Windows a Linux. Se è più di questo, vai con boost.

Onestamente, userei boost :: asio come prima preferenza. Se vuoi davvero rovinarti con l'API socket, puoi utilizzare l'API socket standard in stile BSD su Windows e Linux - è solo che su Windows dovrai collegarti a (e inizializzare) Winsock2, mentre su Linux non avrai una libreria separata per collegarti.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top