【发布时间】:2013-09-06 11:36:27
【问题描述】:
我创建了一个程序,它利用 boost 的 ssl 实现使用async_read_some() 和async_write_some() 向远程服务器发送和接收小数据包。读取和写入被包裹在一个链中以防止并发读取和写入。此外,我为每个创建的包装函数都包含一个互斥锁,以进一步防止并发访问(可能过度杀伤,但不会造成伤害)。写入内容存储在写入队列中,当线程被通知数据可用时将其发送到该队列中。
我遇到的问题是按顺序执行大量写入时出现的,从而导致各种错误,例如 Second Chance Assertion Failed 和 Access Violation。我还收到“解密失败或坏记录 mac”的读取错误。
从我到目前为止所做的研究中,我发现如果同时执行读取和写入,SSL 套接字可能会损坏 - 至少根据讨论 here 和 here 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)));
}
我已经尝试过不同类型的互斥锁,所以我认为这不是问题所在。如果有人知道如何确保我的链正常工作,或者您可以在我的代码/设计中看到一些明显的错误,请告诉我!
【问题讨论】:
-
您是否使用多个线程调用
io_service::run()?如果是这样,当您使用单线程时问题会消失吗? -
请更新您问题中的代码,说明您如何使用显式
strand以确保最多有一个异步 ssl 操作未完成。 -
@SamMiller 我认为问题出在链上。我最初的实现是在读取操作仍在进行时允许多次写入。我现在正在修改一些代码,看看是否可以取得一些进展 - 如果我仍然遇到问题,我会报告我所做的更改。
标签: c++ ssl boost-asio