我正在构建一个必须发送请求和读取响应的tcp客户端,但也必须能够检测来自tcp服务器的不是对请求的响应的传入数据 - 服务器可以发起tx / rx序列。
保持异步读取始终处于活动状态的最佳方法是什么。我尝试了以下方法:
在我的“handle_connect”方法中,我启动了异步读取和异步写入。异步读取如下所示:
size_t bytes_transferred = BUFFER_SIZE; boost::asio::async_read(m_socket, boost::asio::buffer(rcvbuf, bytes_transferred), boost::bind(&CClientSock::handle_read, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
异步写入填充缓冲区然后开始写入:
boost::asio::async_write(m_socket, boost::asio::buffer(sndbuf, request_length), boost::bind(&CClientSock::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
在异步写入处理程序中 - 由于异步读取已经启动,它什么都不做。
这不起作用。应该从服务器对客户端写入的响应中读取的数据永远不会触发异步读取处理程序。我实际上并不确定写入会执行......
这是否可以完成,因为读取和写入不按正常顺序排队?我是否必须开始读取,然后在需要开始写入时取消它?
答案 0 :(得分:4)
由于没有明确的SSCCE /样本,我将强调一些想法:
strand
:Why do I need strand per connection when using boost::asio? 继续阅读,在Actor Based asynchrony中,只需在完成处理程序中发布上一次读取操作的读取操作:
void handle_read(boost::system::error_code ec, size_t bytes_received) {
if (!ec)
{
/* do your usual handling on the incoming data */
boost::asio::async_read(m_socket,
boost::asio::buffer(rcvbuf, bytes_transferred),
boost::bind(&CClientSock::handle_read,
this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
}
}
答案 1 :(得分:1)
好吧,我对最初的问题有了答案,但是他提出了使用股票的可能性,所以我可能没有完全理解。
我最初的问题是重组代码的结果,并没有意识到我的早期代码仅在我测试的情况下工作。我现在使用以下序列工作:
这个序列似乎可以无限重复,没有错误。
关于strands - 代码是多线程的,因此有多个线程,每个线程可能正在管理多个套接字连接。跨线程没有套接字调用 - 也就是说,套接字永远不会被创建套接字的线程以外的代码所操作。但是,项目只有一个io_service对象,这似乎是在多线程应用程序中使用io_service对象的推荐方法。
我是否认为这里没有必要?