boost::asio同じコンピューター上で実行される node.js TCP サーバー アプリケーションへの同期 TCP ソケット接続を確立するために使用しています。Embarcadero 統合ブースト バージョン 1.50 を使用する Windows ビルド 64 ビット アプリケーションで Embarcadero RAD studio XE4 を使用しています。
node.js TCP サーバーがシャットダウンする場合を除いて、問題なく動作します。これが発生すると、C++ クライアント アプリケーションはソケットからの読み取り時に切断を検出しません。ただし、ソケットに書き込むと切断が検出されます。
私の現在のコードは、ブーストのドキュメントとSOに関するさまざまな回答を理解しようとした後に作成されました。コードの読み取り部分は次のとおりです(簡潔にするためにエラー コードのチェックは省略しています)。
boost::system::error_code ec;
boost::asio::io_service io_service;
boost::asio::ip::tcp::socket s(io_service);
boost::asio::ip::tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"),m_port);
ec = s.connect(ep,ec);
std::size_t bytes_available = s.available(ec);
std::vector<unsigned char> data(bytes_available,0);
size_t read_len = boost::asio::read(s, boost::asio::buffer(data),boost::asio::transfer_at_least(bytes_available),ec);
if ((boost::asio::error::eof == ec) || (boost::asio::error::connection_reset == ec))
{
// disconnection
break;
}
これは、ループ内の独自のスレッドで実行され、プログラムがシャットダウンされるまで絶えずデータをポーリングするため、優れたシステムではありません。通常read()、データがない場合はソケットで実行しませんが、この場合は実行します。これは、すべてのドキュメントから、ソケットへの読み取りまたは書き込みを実行するときにのみソケットの切断が検出されると思われるためです。問題は、node.js アプリケーションがシャットダウンしたときに、上記のコードが切断をまったく検出しないことです。私が書いている場合はそれを検出します(コードの書き込み部分は、検出のために読み取りと同じboost::asio::error`エラーを使用しています)が、読み取り時には検出しません。
明らかに、利用可能なバイト量よりも大きいバイト量の読み取りを実行することはできません。そうしないと、スレッドがブロックされ、後でスレッド ループで書き込みを実行できなくなります。
エラー状態を検出するための別の特定のブースト エラー コードがありませんか? または、ゼロ長の読み取りに特に問題がありますか。その場合、他に利用できるオプションはありますか?
現在、node.jsサーバーが特定のメッセージをソケットに書き出すようにしています。これは、シャットダウン時に検出され、クライアントエンドを自分で閉じます。ただし、これはちょっとしたハックであり、可能であれば、切断を検出するためのクリーンな方法を希望します。