質問
私はソケット関連のものを C++ で開発しようとしているのですが、ソフトウェアを最初から Windows と Linux 間でできるだけ移植できるようにしたいと考えています (後で移植可能にするのは難しいことです)。
さまざまなライブラリを調べましたが、C++ 用のライブラリがあります。 アルヘムネット もちろん、boost::asio もあります。boost::asio は非常に有望に見えますが、これほど小規模なアプリケーションでは非常に大きな依存関係になるでしょう。
自分で書く価値はあるのでしょうか、それともライブラリを使用するだけでよいでしょうか?自分でやる場合、主な落とし穴は何でしょうか?
解決
WinsocksはPosixソケットとあまり互換性がありません:
- Winsocksでは、ソケットのタイプは
SOCKET
です。 Posixでは、単なるファイル記述子(int
)であり、通常のread()
およびwrite()
呼び出しを実行できます。 - 同じ方法でエラーを返しません。
- これらは、
recv()
およびsend()
の一部のオプションをサポートしていません。 - Winsocksライブラリを2つの特別な関数で初期化し、ユニット化する必要があります。
- Windowsソケットを
shutdown()
またはclose()
で閉じることができるとは思わない。代わりにclosesocket()
のようなものです。
さらに違いがあるはずですが、それは今覚えていることです。 Winsocksとの移植性が必要な場合は、ソケットを閉じたり、エラーメッセージを出力したりするための小さなライブラリがあります。
個人的にはboost::asio
を使用します(ただし、使用したことはありません)。
他のヒント
私はソケットに関するポータブルなラッパーをいくつか開発しました。WinSock2 イベントで構成される、後戻りできないつまらない道を歩まないように注意してください。それ以外に、私が考える最大の違いは次のとおりです。
- Windows でネットワークを開始するには、次の呼び出しを行う必要があります。
::WSAStartup()
, Windows でシャットダウンするには、次を実行します。::WSACleanup()
;Linuxでは何もしませんが、 close()
Linuxではclosesocket()
Windowsでは、- デフォルトのバッファ サイズはドライバとオペレーティング システムの両方で異なるため、必ず次を使用して設定してください。
SO_RCVBUF
そしてSO_SNDBUF
, - SO_REUSEADDR は Windows 上でアドレスを盗み、Linux 上で頻繁に再オープンできるようにします。おそらくこのフラグは Linux でのみ使用したいでしょう。
- ソケットをノンブロッキングに使用する
::ioctlsocket()
Windowsでは、::fcntl()
Linuxでは、 - ヘッダファイルが違うので、
<sys/socket.h>
そして Linux の友人たち、<WinSock.h>
Windowsでは、 - ポータブルにするには、おそらく最も簡単な方法は次のとおりです
::select()
データが到着するのを待つため、 fd_set
Windows/Linux ではまったく異なります。これは、初期化を最適化する必要がある場合にのみ関係します。fd_set
任意のソケットを追加/削除するときなど、- Windows では、ソケットにハングしているスレッドはソケットが閉じられるとエラー コードとともに解放されますが、Linux ではスレッドは待機したままになります。たとえば、スレッドがソケットをブロックしている場合は、
::recvfrom()
, の使用を検討してもよいでしょう。::sendto()
Linux で停止しているスレッドを解放します。
他に必要なものはすべて、Låda から実行できました。
<!> quot; Adaptive Communications Environment <!> quot;をご覧ください。 (ACE)ライブラリ: (ACEホームページ) Windows、MacOS、Linuxをサポートするポータブルライブラリにまとめられた、優れた抽象化と柔軟性を提供します。 それは少し急な学習曲線を持っていますが、私はそれから非常に良い値を得ました。
どのくらいのソケットを使用しますか?ソケットが非常に高レベル(オープン、読み取り、書き込み)で、WindowsからLinuxまで完全に機能するアプリをいくつか作成しました。それ以上であれば-ブーストしてください。
正直、boost :: asioを最初の設定として使用します。ソケットAPIを本当に使いたくない場合は、WindowsとLinuxの両方で標準のBSDスタイルのソケットAPIを使用できます。Windowsでは、Winsock2にリンク(および初期化)する必要があります。 Linuxでは、リンクするための別個のライブラリはありません。
こちらをご覧ください... http://sourceforge.net/projects/cpp-ソケット/