【发布时间】:2021-11-18 14:52:43
【问题描述】:
我有一个代表套接字的cnx 类,它还必须有一个计时器,如果客户端停留超过cnx::timeout_mili 毫秒而没有响应,那么我将关闭连接。每个计时器将在建立连接时启动,或者在实例化 cnx 对象时启动。套接字部分工作正常,现在当我尝试将计时器添加到 cnx 类时,它的构建失败并出现以下错误:
In file included from /home/pcuser/src/boost_1_71_0/boost/asio/impl/execution_context.hpp:18,
from /home/pcuser/src/boost_1_71_0/boost/asio/execution_context.hpp:409,
from /home/pcuser/src/boost_1_71_0/boost/asio/detail/scheduler.hpp:21,
from /home/pcuser/src/boost_1_71_0/boost/asio/system_context.hpp:19,
from /home/pcuser/src/boost_1_71_0/boost/asio/impl/system_executor.hpp:22,
from /home/pcuser/src/boost_1_71_0/boost/asio/system_executor.hpp:129,
from /home/pcuser/src/boost_1_71_0/boost/asio/associated_executor.hpp:21,
from /home/pcuser/src/boost_1_71_0/boost/asio.hpp:21,
from /home/pcuser/src/cpp-server/comum.h:9,
from /home/pcuser/src/cpp-server/cnx.h:4,
from /home/pcuser/src/cpp-server/cnx.cpp:1:
/home/pcuser/src/boost_1_71_0/boost/asio/basic_deadline_timer.hpp: In instantiation of ‘void boost::asio::basic_deadline_timer<Time, TimeTraits, Executor>::initiate_async_wait::operator()(WaitHandler&&, boost::asio::basic_deadline_timer<Time, TimeTraits, Executor>*) const [with WaitHandler = void (cnx::*)(const boost::system::error_code&); Time = boost::posix_time::ptime; TimeTraits = boost::asio::time_traits<boost::posix_time::ptime>; Executor = boost::asio::executor]’:
/home/pcuser/src/boost_1_71_0/boost/asio/async_result.hpp:82:49: required from ‘static boost::asio::async_result<CompletionToken, Signature>::return_type boost::asio::async_result<CompletionToken, Signature>::initiate(Initiation&&, RawCompletionToken&&, Args&& ...) [with Initiation = boost::asio::basic_deadline_timer<boost::posix_time::ptime>::initiate_async_wait; RawCompletionToken = void (cnx::*)(const boost::system::error_code&); Args = {boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::executor>*}; CompletionToken = void (cnx::*)(const boost::system::error_code&); Signature = void(boost::system::error_code); boost::asio::async_result<CompletionToken, Signature>::return_type = void]’
/home/pcuser/src/boost_1_71_0/boost/asio/async_result.hpp:257:25: required from ‘typename std::enable_if<boost::asio::detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, typename boost::asio::async_result<typename std::decay<_Tp>::type, Signature>::return_type>::type boost::asio::async_initiate(Initiation&&, CompletionToken&, Args&& ...) [with CompletionToken = void (cnx::*)(const boost::system::error_code&); Signature = void(boost::system::error_code); Initiation = boost::asio::basic_deadline_timer<boost::posix_time::ptime>::initiate_async_wait; Args = {boost::asio::basic_deadline_timer<boost::posix_time::ptime, boost::asio::time_traits<boost::posix_time::ptime>, boost::asio::executor>*}; typename std::enable_if<boost::asio::detail::async_result_has_initiate_memfn<CompletionToken, Signature>::value, typename boost::asio::async_result<typename std::decay<_Tp>::type, Signature>::return_type>::type = void; typename boost::asio::async_result<typename std::decay<_Tp>::type, Signature>::return_type = void; typename std::decay<_Tp>::type = void (cnx::*)(const boost::system::error_code&)]’
/home/pcuser/src/boost_1_71_0/boost/asio/basic_deadline_timer.hpp:629:73: required from ‘typename boost::asio::async_result<typename std::decay<_Functor>::type, void(boost::system::error_code)>::return_type boost::asio::basic_deadline_timer<Time, TimeTraits, Executor>::async_wait(WaitHandler&&) [with WaitHandler = void (cnx::*)(const boost::system::error_code&); Time = boost::posix_time::ptime; TimeTraits = boost::asio::time_traits<boost::posix_time::ptime>; Executor = boost::asio::executor; typename boost::asio::async_result<typename std::decay<_Functor>::type, void(boost::system::error_code)>::return_type = void; typename std::decay<_Functor>::type = void (cnx::*)(const boost::system::error_code&)]’
/home/pcuser/src/cpp-server/cnx.cpp:15:25: required from here
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:376:62: error: static assertion failed: WaitHandler type requirements not met
373 | sizeof(boost::asio::detail::one_arg_handler_test( \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
374 | boost::asio::detail::rvref< \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
375 | asio_true_handler_type>(), \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
376 | static_cast<const boost::system::error_code*>(0))) == 1, \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:105:20: note: in definition of macro ‘BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT’
105 | static_assert(expr, msg);
| ^~~~
/home/pcuser/src/boost_1_71_0/boost/asio/basic_deadline_timer.hpp:647:7: note: in expansion of macro ‘BOOST_ASIO_WAIT_HANDLER_CHECK’
647 | BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:376:62: note: ‘(sizeof (boost::asio::detail::one_arg_handler_test<void (cnx::*)(const boost::system::error_code&)>(boost::asio::detail::rvref<void (cnx::*)(const boost::system::error_code&)>(), 0)) == 1)’ evaluates to false
373 | sizeof(boost::asio::detail::one_arg_handler_test( \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
374 | boost::asio::detail::rvref< \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
375 | asio_true_handler_type>(), \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
376 | static_cast<const boost::system::error_code*>(0))) == 1, \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~~~
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:105:20: note: in definition of macro ‘BOOST_ASIO_HANDLER_TYPE_REQUIREMENTS_ASSERT’
105 | static_assert(expr, msg);
| ^~~~
/home/pcuser/src/boost_1_71_0/boost/asio/basic_deadline_timer.hpp:647:7: note: in expansion of macro ‘BOOST_ASIO_WAIT_HANDLER_CHECK’
647 | BOOST_ASIO_WAIT_HANDLER_CHECK(WaitHandler, handler) type_check;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/pcuser/src/boost_1_71_0/boost/asio/detail/handler_type_requirements.hpp:280:36: error: must use ‘.*’ or ‘->*’ to call pointer-to-member function in ‘boost::asio::detail::lvref<void (cnx::*)(const boost::system::error_code&)>() (...)’, e.g. ‘(... ->* boost::asio::detail::lvref<void (cnx::*)(const boost::system::error_code&)>()) (...)’
279 | boost::asio::detail::lvref< \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
280 | asio_true_handler_type>()( \
| ~~~~~~~~~~~~~~~~~~~~~~~~~^~~
281 | boost::asio::detail::lvref<const boost::system::error_code>()), \
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
/home/pcuser/src/boost_1_71_0/boost/asio/basic_socket.hpp:1817:7: note: in expansion of macro ‘BOOST_ASIO_CONNECT_HANDLER_CHECK’
1817 | BOOST_ASIO_CONNECT_HANDLER_CHECK(ConnectHandler, handler) type_check;
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
make[2]: *** [CMakeFiles/Server.dir/build.make:90: CMakeFiles/Server.dir/cnx.cpp.o] Error 1
make[2]: *** Waiting for unfinished jobs....
make[1]: *** [CMakeFiles/Makefile2:83: CMakeFiles/Server.dir/all] Error 2
make: *** [Makefile:91: all] Error 2
我的代码如下:
cnx.h
#ifndef CNX_H
#define CNX_H
#include <boost/asio.hpp>
using boost::asio::ip::tcp;
typedef boost::asio::io_service ioservice;
using namespace std;
class cnx
{
public:
inline static int timeout_mili = 10000;
cnx(ioservice& io);
void timer_counter_reset();
bool conectado;
private:
tcp::socket s;
boost::asio::io_service timer_io;
boost::asio::deadline_timer cnx_timer;
void timer_ended(const boost::system::error_code& e);
};
#endif // CNX_H
cnx.cpp
#include "cnx.h"
cnx::cnx(ioservice& io) :
s(tcp::socket(io)),
conectado(false),
cnx_timer(boost::asio::deadline_timer(timer_io, boost::posix_time::milliseconds(cnx::timeout_mili)))
{
timer_io.run();
cnx_timer.async_wait(&cnx::timer_ended);
}
// I'll call this outsite so the timer gets reset and restart couting
void cnx::timer_counter_reset()
{
cnx_timer.cancel();
cnx_timer.async_wait(&cnx::timer_ended);
}
void cnx::timer_ended(const boost::system::error_code& e)
{
if(e){
cout << "cnx id " << id << " resetted timer" << endl;
return;
}
this->conectado = false;
}
我不知道我在函数签名上做错了什么。我的问题似乎还没有得到回答here。提前致谢。
编辑
所以,问题似乎是在 async_wait 调用中引用方法 &cnx::timer_ended 时,我在 cnx.h 中添加了一个测试函数,如下所示:
inline static void testtt(const boost::system::error_code& e)
{
cout << "testtt" << endl;
return;
}
并将 async_await 调用从
cnx_timer.async_wait(&cnx::timer_ended);转cnx_timer.async_wait(cnx::testtt);
它奏效了。但是我仍然不知道如何解决它,因为我需要更改 cnx 对象的每个实例的值,所以我不能使用静态函数......有什么想法吗?
编辑 2 即使现在正在编译,代码也没有按预期工作,函数“testtt”根本没有被触发。
【问题讨论】:
标签: c++ boost c++17 boost-asio asio