async_read_some()
ブーストの ssl 実装を利用して、 とを使用してリモート サーバーに小さなパケットを送受信するプログラムを作成しましたasync_write_some()
。読み取りと書き込みはストランドにラップされ、読み取りと書き込みが同時に行われるのを防ぎます。さらに、それぞれに対して作成したラッパー関数には、同時アクセスをさらに防止するためのミューテックスが含まれています (やり過ぎかもしれませんが、問題はありません)。書き込みは書き込みキューに格納され、データが使用可能であることがスレッドに通知されると送信されます。
私が経験している問題は、多数の書き込みが連続して実行されたときに発生し、Second Chance Assertion Failed や Access Violation などのさまざまなエラーが発生します。また、「復号化に失敗したか、レコード mac が正しくありません」という読み取りエラーが発生します。
これまでに行った調査から、読み取りと書き込みが同時に実行されると、SSL ソケットが破損する可能性があることがわかりました。彼はまた、彼が使用していたストランドが機能していなかったと述べていますが、私は彼の解決策を理解していません. これは、同時読み取りと書き込みを防ぐために使用しようとしている方法が原因で発生している問題には意味があります。
私が使用してきた回避策は、順次書き込みを抑制して、それぞれの間に少なくとも 20 ミリ秒のギャップがあるようにすることです。これより少ないと、エラーが発生し始めます。ただし、この回避策は優れたものではありません。ある時点でまだ同時読み取り/書き込みが発生してエラーが発生する可能性があるためです。
私の読み取り/書き込みコードの概要は次のとおりです。
void client::write(std::string message, char packetType) {
boost::lock_guard<boost::shared_mutex> lock(writeInProgressMutex);
std::string preparedMessage = prepareWrite(message, packetType);
char data_sent[2048];
for(std::string::size_type i = 0; i < preparedMessage.size(); ++i) {
data_sent[i] = preparedMessage[i];
if (i + 1 == preparedMessage.size()) {
data_sent[i+1] = NULL;
}
}
socket_->async_write_some(boost::asio::buffer(data_sent), strand_.wrap(boost::bind(&client::handle_write, this, boost::asio::placeholders::error)));
}
void client::read() {
boost::lock_guard<boost::shared_mutex> lock(readInProgressMutex);
socket_->async_read_some(boost::asio::buffer(data_), strand_.wrap(boost::bind(&client::handle_read, this, boost::asio::placeholders::error)));
}
さまざまな種類のミューテックスを試してみたので、それが問題だとは思いません。私のストランドが機能していることを確認する方法を誰かが知っている場合、または私のコード/デザインに明らかなエラーが見られる場合は、お知らせください!