我自己与Boost.Asio的持续传奇中的另一个......
我有一个简单的异步客户端和服务器,它使用async_write和async_read进行通信。客户端可以成功地将字节写入套接字,但服务器永远不会看到它们;我在服务器上的读取处理程序失败并显示“取消操作”。
我倾向于认为这可能是客户端在服务器试图读取并失败之后写入数据的时间问题,但我认为数据会等待无论如何在套接字上(除非套接字在此期间已关闭)。
为了测试这个,我只是在错误处理程序中重新运行读操作,即
read_handler()
{
if (!error) {
/* bytes read */
} else {
async_read(socket, buffer, read_handler)
}
}
但通过拨打pthread_mutex_lock
,所有这些让我感到async_receive
中的段错误。
有人能指出我的任何相关信息的方向(或者,更好的是,告诉我我做错了什么;))?
更新:服务器和客户端基于Asio文档中的聊天服务器示例,客户端和服务器都在同一进程下运行(这可能是一个问题吗?多思考一下他们都使用相同的io_service ...);异步和使用Boost 1.44.0。我正在研究OS X,但这在Linux上也是可以重现的。
UPDATE II :我的预感是正确的,如果给服务器和客户端单独的io_service对象,async_read会看到套接字上的字节。这仍然会导致boost::asio::detail::kqueue_reactor::post_immediate_completion
中的段错误似乎源于io_service.run()
。在我进一步讨论之前,使用单独的io_service
个对象是正确的方法吗?
答案 0 :(得分:28)
当套接字为closed或取消时,将发送取消操作(operation_aborted错误代码)。
很可能你的连接超出了范围。
也许正好在我遇到你忘了将async_handlers附加到shared_from_this()指针。 即你应该像这样附上你的处理程序:
async_read(m_socket,
boost::asio::buffer((void*)m_buffer, m_header_size),
boost::bind(&TcpConnection::handleRead,
shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
并且不喜欢这样:
async_read(m_socket,
boost::asio::buffer((void*)m_buffer, m_header_size),
boost::bind(&TcpConnection::handleRead,
this, //<- This will go out of scope and the socket will be closed
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));