2009-05-06 12 views
6

sto per sviluppare alcune prese roba connessi in C++ e vorrei il software di essere il più portabile tra Windows e Linux il più possibile fin dall'inizio (il che rende più tardi portatile è difficile.)Winsock 2 portabilità

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

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

risposta

3

Winsocks non sono molto compatibili con prese Posix:

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

Ci devono essere più differenze, ma è quello che posso ricordare adesso. 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ò).

+0

Ok, vedrò cosa faccio. Boost :: asio ha anche un'interfaccia ICMP che è molto carina quindi al momento sembra che userò quello. – Skurmedel

+0

shutdown () è una funzione valida per i socket di Windows. È tuttavia corretto utilizzare closesocket(). –

+1

closesocket è solo la versione di Windows di chiusura, in modo che non debbano sovraccaricare la funzione di chiusura. t DEVI chiudere un file/socket, ma se non lo fai, potresti ottenere una perdita di dati. WSAGetLastError è solo la funzione di Windows per ottenere l'errore, dal momento che l'API di Windows non supportava errno nello stesso modo. E per i socket, POSIX supporta le versioni "send" e "recv" di read e Scrivi. – david

1

Onestamente, vorrei usare boost :: asio come prima preferenza. Se vuoi davvero scendere e sporcare con l'API socket, puoi usare l'API standard socket BSD su Windows e Linux - è solo che su Windows dovrai collegare (e inizializzare) Winsock2, mentre su Linux non avrai una libreria separata da collegare.

+0

Grazie per il consiglio. +1 questo, può solo segnare una risposta :( – Skurmedel

1

Quanta roba di socket userete? Ho fatto diverse app in cui il materiale del socket era di alto livello (aperto, letto, scritto) e funzionava perfettamente da Windows a Linux. Se è più di questo, vai con boost.

+0

Inizialmente, sarebbe un livello molto basso, come aprire una connessione, scrivere qualcosa, leggere, uscire. Probabilmente potrebbe crescere per includere comunque le cose di Http. – Skurmedel

+0

Grazie per il consiglio . +1 questo, può solo segnare una risposta :( – Skurmedel

5

Ho sviluppato alcuni involucri portatili attorno alle prese. Assicurati di non andare giù per il vicolo cieco di non ritorno che è costituito da eventi WinSock2.Oltre a questo, come la vedo io, le maggiori differenze sono:

  • per avviare rete in Windows, è necessario chiamare ::WSAStartup(), per spegnerlo in Windows, eseguire ::WSACleanup(); in Linux non fare nulla,
  • close() in Linux è closesocket() in Windows,
  • dimensioni del buffer di default differiscono tra i due piloti e sistemi operativi, quindi assicuratevi di impostarli utilizzando SO_RCVBUF e SO_SNDBUF,
  • SO_REUSEADDR ruba l'indirizzo su Windows , consente frequenti riaperture su Linux; si sarebbe probabilmente solo desidera utilizzare questo flag in Linux,
  • facendo un socket non bloccante utilizza ::ioctlsocket() in Windows, ::fcntl() in Linux,
  • i file header sono diversi, <sys/socket.h> e gli amici in Linux, <WinSock.h> in Windows,
  • andare portatile, il modo più semplice è probabilmente quello di utilizzare ::select() attendere la ricezione di dati,
  • fd_set s sono totalmente diverso su Windows/Linux; questo è rilevante solo se è necessario ottimizzare l'inizializzazione di fd_set s, come quando si aggiungono/rimuovono socket arbitrari,
  • in Windows, qualsiasi thread che si blocca sul socket viene rilasciato con un codice di errore quando il socket è chiuso, in Linux il thread rimane in attesa. Se il thread sta bloccando il socket con ad esempio ::recvfrom(), potresti prendere in considerazione l'utilizzo di ::sendto() per rilasciare il thread di stallo sotto Linux.

Tutto il resto che ho mai avuto bisogno ha appena lavorato fuori dalla låda.

+0

Consigli molto utili. Tackar och bugar;). – Skurmedel

+0

Sei più välkommen! –

2

Date un'occhiata alla biblioteca "Adaptive Communications Environment" (ACE): (ACE Home Page) fornisce alcune astrazioni belle e un sacco di flessibilità tutto arrotolato in una biblioteca portatile che supporta Windows, MacOS e Linux. Ha una curva di apprendimento piuttosto ripida, ma ho ottenuto un ottimo rapporto.

+0

Grazie per il suggerimento. – Skurmedel