我使用boost :: asio编写了一个小型tcp客户端,提供了以下功能:
typedef boost::function<void(const bs::error_code& errCode, size_t bytesTransferred)> ReadHandler;
void CTcpClient::AsyncRead2(std::vector<char>& data, size_t length, ReadHandler readCompletedCallback)
{
async_read(m_tcpData->socket, ba::buffer(data, length), readCompletedCallback);
}
我的想法是为用户提供我的TcpClient类异步操作,而不用担心线程处理,io_services等。
现在,从我的unittest类调用上述函数的代码如下所示:
CTestTcpClient标题
class CTestTcpClient : public ::testing::Test
{
public:
CTestTcpClient(void);
virtual ~CTestTcpClient(void);
struct ReadCompletedHandler
{
ReadCompletedHandler() : m_isCompleted(false){};
void operator()(const boost::system::error_code& errCode, size_t bytesTransferred)
{
m_isCompleted = true; // my breakpoint here, checking this pointer
};
bool isCompleted(void)
{
return m_isCompleted;
}
private:
bool m_isCompleted;
};
ReadCompletedHandler m_readHandler;
};
CTestTcpClient来源
TEST_F(CTestTcpClient, testAsynchronousRead_Success)
{
CTcpClient client(testService);
// Skipped code to setup echo server, connecting and sending of data
// Receive echo
vector<char> receiveBuffer(TESTDATA_SIZE);
client.AsyncRead2(receiveBuffer, TESTDATA_SIZE, m_readHandler);
while (!m_readHandler.isCompleted())
{
client.Wait(200);
}
}
现在问题是:while循环永远不会退出,因为is_completed标志是在m_readHandler的 copy 中设置的。如果我在我的处理程序的operator()中设置断点,我可以检查并比较这个指针。似乎boost :: asio正在复制我的处理程序,在那里调用operator()并返回。我的原始处理程序从未被触及过。
增强文档说,副本将根据需要由处理程序组成。所以这似乎没问题,但我能做些什么来达到理想的行为?
感谢您的帮助
答案 0 :(得分:1)
我用于完成处理程序的典型习惯是boost::bind
使用boost::shared_from_this
的成员函数来确保有问题的对象不会超出范围。这在几乎所有Boost.Asio examples中都很普遍。
如果您不想更改设计,可以尝试boost::ref
,例如:
client.AsyncRead2(receiveBuffer, TESTDATA_SIZE, boost::ref(m_readHandler) );