我创建了一个程序,该程序利用 boost 的 ssl 实现使用async_read_some()
and向远程服务器发送和接收小数据包async_write_some()
。读取和写入被包裹在一个链中以防止并发读取和写入。此外,我为每个创建的包装函数都包含一个互斥锁,以进一步防止并发访问(可能是矫枉过正,但不会造成伤害)。写入存储在写入队列中,当线程被通知数据可用时,它们被发送到该队列中。
我遇到的问题是在顺序执行大量写入时发生的,从而导致各种错误,例如 Second Chance Assertion Failed 和 Access Violation。我还收到“解密失败或坏记录 mac”的读取错误。
从我到目前为止所做的研究中,我发现如果同时执行读取和写入,SSL 套接字可能会损坏 - 至少根据此处和此处的讨论,OP 的症状与我的非常相似。他还说他使用的链不起作用,但我不明白他的解决方案。由于我试图用来防止并发读写的方法,这对于我遇到的问题是有意义的。
我一直在使用的一种解决方法是限制顺序写入,以便每次写入之间至少有 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)));
}
我已经尝试过不同类型的互斥锁,所以我认为这不是问题。如果有人知道如何确保我的链正常工作,或者您可以在我的代码/设计中看到一些明显的错误,请告诉我!