我有一台服务器,当前正在使用异步IO来(1)接受来自cin的数据并通过UNIX套接字发送该输入,以及(2)接受UNIX套接字上的数据,解析该数据并发回响应。 / p>
当我解析数据时,如何阻止解析器中出现的I / O(下例中的ParseJSON(data_.data())
)?在返回parsed
async_write
之前,它应该通过cin提出问题并收集这些问题的答案;目前,问题已打印出来,但在将答案输入cin之前会发送响应。
socket_
是来自stream_protocol::socket
的{{1}},FWIW。
boost::asio
ParseJSON中发生的缩写版本(某些字符串替换为<>用于保密):
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
string parsed = ParseJSON(data_.data());
async_write(socket_,
buffer(parsed),
boost::bind(&session::handle_write,
shared_from_this(),
placeholders::error));
}
}
void handle_write(const boost::system::error_code& error)
{
if (!error)
{
socket_.async_read_some(buffer(data_),
boost::bind(&session::handle_read,
shared_from_this(),
placeholders::error,
placeholders::bytes_transferred));
}
}
答案 0 :(得分:1)
如果ParseJSON()
对cin
进行阻止性读取,那么它将阻止这意味着handle_read()
在async_write()
返回之前不会执行ParseJSON()
。
我认为问题是parsed
是一个堆栈变量。 handle_read()
很可能在数据实际写入之前返回,parsed
将被销毁。在调用完成处理程序(async_write()
)之前,传递给handle_write
的数据必须有效。
如果handle_read()
和handle_write()
是成员函数,您可以添加parsed
成员来保存数据。或者,您可以将parsed
包装在绑定到handle_write()
的shared_ptr中,如下所示:
void handle_read(const boost::system::error_code& error,
size_t bytes_transferred)
{
if (!error)
{
string *ps = new string(ParseJSON(data_.data()));
boost::shared_ptr<string> pParsed(ps);
async_write(socket_,
buffer(*pParsed),
boost::bind(&session::handle_write,
shared_from_this(),
pParsed,
placeholders::error));
}
}
void handle_write(boost::shared_ptr<string> pParsed,
const boost::system::error_code& error)
{
if (!error)
{
socket_.async_read_some(buffer(data_),
boost::bind(&session::handle_read,
shared_from_this(),
placeholders::error,
placeholders::bytes_transferred));
}
}
当完成处理程序退出时,对shared_ptr的最后一个引用将消失,ps
将被销毁。