У меня проблема с C ++ TCP Server (с использованием boost asio).
В обычном клиенте многие клиенты подключаются к серверу нормально.Но если каждый клиент подключается и отключается от сервера 10 раз в секунду, ядро сервера некоторое время.
(1) создает сервер следующим образом:
void ClientConnection::start()
{
socket_.async_read_some(boost::asio::buffer(buffer_),
strand_.wrap(
boost::bind(&connection::handle_read, shared_from_this(),
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred)));
}
void ClientConnection::closeSocket() {
mStrand.post(boost::bind(&ClientConnection::innerCloseSocket, this->shared_from_this()));
}
void ClientConnection::innerCloseSocket() {
boost::system::error_code error;
mSocket.close(error);
LOG_INFO("Close client[" << mClientId << "] socket connection"); //line:216
}
ClientConnection::~ClientConnection() {
}
(2) hand_read вот так:
void ClientConnection::handle_read(const boost::system::error_code& e,
std::size_t bytes_transferred)
{
if (!e)
{
//read data and use it
}
else { //error occurs
closeSocket();
boost::shared_ptr<DisConnectCommand> cmd(new DisConnectCommand());
cmd->setClient(this->weak_from_this()); //here set this connection weak_ptr
putCmd(cmd); //do something in other thread.
}
}
(3) handle_write наподобие этого:
void ClientConnection::handle_write(const boost::system::error_code& e)
{
if (!e)
{
//send data
}
else { //error occurs
closeSocket();
boost::shared_ptr<DisConnectCommand> cmd(new DisConnectCommand());
cmd->setClient(this->weak_from_this()); //here set this connection weak_ptr
putCmd(cmd); //do something in other thread.
}
}
core
, но когда множество клиентов подключается к серверу, ядро сервера.Ядру нравится, что соединение было разорвано во время буксировки, память - ошибка.
bt вот так:
#0 0x00007f6e3aa561f7 in raise () from /lib64/libc.so.6
#1 0x00007f6e3aa578e8 in abort () from /lib64/libc.so.6
#2 0x00007f6e3b35c9d5 in __gnu_cxx::__verbose_terminate_handler() () from /lib64/libstdc++.so.6
#3 0x00007f6e3b35a946 in ?? () from /lib64/libstdc++.so.6
#4 0x00007f6e3b35a973 in std::terminate() () from /lib64/libstdc++.so.6
#5 0x00007f6e3b35ab93 in __cxa_throw () from /lib64/libstdc++.so.6
#6 0x00007f6e3b35b12d in operator new(unsigned long) () from /lib64/libstdc++.so.6
#7 0x00007f6e3b3b9c79 in std::string::_Rep::_S_create(unsigned long, unsigned long, std::allocator<char> const&) () from /lib64/libstdc++.so.6
#8 0x00007f6e3b3ba8bb in std::string::_Rep::_M_clone(std::allocator<char> const&, unsigned long) () from /lib64/libstdc++.so.6
#9 0x00007f6e3b3ba964 in std::string::reserve(unsigned long) () from /lib64/libstdc++.so.6
#10 0x00007f6e3b3baa28 in std::string::append(std::string const&) () from /lib64/libstdc++.so.6
#11 0x00007f6e3be5c4c8 in log4cxx::helpers::CharMessageBuffer::operator<< (this=0x7f6e20ff8750, msg=...) at messagebuffer.cpp:31
#12 0x00000000008a3a05 in ClientConnection::internalCloseSocket (this=0x7f6e046fefd0) at src/business/ClientConnection.cpp:216
#13 0x00000000008b620a in boost::_mfi::mf0<void, ClientConnection>::call<boost::shared_ptr<ClientConnection> > (this=0x7f6e20ff89c0, u=...)
at externals/boost/include/boost/bind/mem_fn_template.hpp:40
#14 0x00000000008b5c79 in boost::_mfi::mf0<void, ClientConnection>::operator()<boost::shared_ptr<ClientConnection> > (this=0x7f6e20ff89c0, u=...)
at externals/boost/include/boost/bind/mem_fn_template.hpp:55
#15 0x00000000008b5416 in boost::_bi::list1<boost::_bi::value<boost::shared_ptr<ClientConnection> > >::operator()<boost::_mfi::mf0<void, ClientConnection>, boost::_bi::list0> (
this=0x7f6e20ff89d0, f=..., a=...) at externals/boost/include/boost/bind/bind.hpp:259
#16 0x00000000008b4997 in boost::_bi::bind_t<void, boost::_mfi::mf0<void, ClientConnection>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<ClientConnection> > > >::operator() (this=0x7f6e20ff89c0) at externals/boost/include/boost/bind/bind.hpp:1294
#17 0x00000000008b3667 in boost::asio::asio_handler_invoke<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ClientConnection>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<ClientConnection> > > > > (function=...) at externals/boost/include/boost/asio/handler_invoke_hook.hpp:69
#18 0x00000000008b235a in boost_asio_handler_invoke_helpers::invoke<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ClientConnection>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<ClientConnection> > > >, boost::_bi::bind_t<void, boost::_mfi::mf0<void, ClientConnection>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<ClientConnection> > > > > (
function=..., context=...) at externals/boost/include/boost/asio/detail/handler_invoke_helpers.hpp:37
#19 0x00000000008b0ee3 in boost::asio::detail::completion_handler<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ClientConnection>, boost::_bi::list1<boost::_bi::value<boost::shared_ptr<ClientConnection> > > > >::do_complete (owner=0x1a5a5c0, base=0x7f6e28018f30) at externals/boost/include/boost/asio/detail/completion_handler.hpp:68
#20 0x00000000007c3ef4 in boost::asio::detail::task_io_service_operation::complete (this=0x7f6e28018f30, owner=..., ec=..., bytes_transferred=0)
at externals/boost/include/boost/asio/detail/task_io_service_operation.hpp:38
#21 0x00000000007c7937 in boost::asio::detail::strand_service::do_complete (owner=0x1a5a5c0, base=0x7f6df001ab40, ec=...) at externals/boost/include/boost/asio/detail/impl/strand_service.ipp:167
#22 0x00000000007c3ef4 in boost::asio::detail::task_io_service_operation::complete (this=0x7f6df001ab40, owner=..., ec=..., bytes_transferred=0)
at externals/boost/include/boost/asio/detail/task_io_service_operation.hpp:38
#23 0x00000000007c5dde in boost::asio::detail::task_io_service::do_run_one (this=0x1a5a5c0, lock=..., this_thread=..., ec=...) at externals/boost/include/boost/asio/detail/impl/task_io_service.ipp:372
#24 0x00000000007c5845 in boost::asio::detail::task_io_service::run (this=0x1a5a5c0, ec=...) at externals/boost/include/boost/asio/detail/impl/task_io_service.ipp:149
#25 0x00000000007c60cf in boost::asio::io_service::run (this=0x1a54b10) at externals/boost/include/boost/asio/impl/io_service.ipp:59
#26 0x00000000008c27b6 in ProcessModule::threadRun (this=0x1a54b10) at src/business/ProcessModule.cpp:149
#27 0x00000000008c82e7 in boost::_mfi::mf0<void, ProcessModule>::operator() (this=0x1b0aee8, p=0x1a54b10) at externals/boost/include/boost/bind/mem_fn_template.hpp:49
#28 0x00000000008c824a in boost::_bi::list1<boost::_bi::value<ProcessModule*> >::operator()<boost::_mfi::mf0<void, ProcessModule>, boost::_bi::list0> (this=0x1b0aef8,
f=..., a=...) at externals/boost/include/boost/bind/bind.hpp:259
#29 0x00000000008c81f9 in boost::_bi::bind_t<void, boost::_mfi::mf0<void, ProcessModule>, boost::_bi::list1<boost::_bi::value<ProcessModule*> > >::operator() (
this=0x1b0aee8) at externals/boost/include/boost/bind/bind.hpp:1294
#30 0x00000000008c811a in boost::detail::thread_data<boost::_bi::bind_t<void, boost::_mfi::mf0<void, ProcessModule>, boost::_bi::list1<boost::_bi::value<ProcessModule*> > > >::run (this=0x1b0ad30) at externals/boost/include/boost/thread/detail/thread.hpp:116
(gdb) p *this
$1 = {<boost::enable_shared_from_this<ClientConnection>> = {weak_this_ = {px = 0x7f981c4cf720, pn = {pi_ = 0x7f981c2feca0}}}, <boost::noncopyable_::noncopyable> = {<No data fields>},
mIoService = @0x1333b10,
mSocket = {<boost::asio::basic_socket<boost::asio::ip::tcp, boost::asio::stream_socket_service<boost::asio::ip::tcp> >> = {<boost::asio::basic_io_object<boost::asio::stream_socket_service<boost::asio::ip::tcp>, true>> = {implementation = {<boost::asio::detail::reactive_socket_service_base::base_implementation_type> = {socket_ = -1, state_ = 0 '\000', reactor_data_ = 0x0}, protocol_ = {family_ = 2}},
service_ = 0x1371560}, <boost::asio::socket_base> = {static message_peek = 2, static message_out_of_band = 1, static message_do_not_route = 4, static message_end_of_record = 128,
static max_connections = 128}, <No data fields>}, <No data fields>}, mStrand = {service_ = @0x13e5510, impl_ = 0x7f98080500a0},
ClientConnection.cpp: 216 равно
LOG_INFO("Close client[" << mClientId << "] socket connection");//line:216
mClientId неверное значение.похоже, этот класс уничтожен.
слабый ptr вроде:
(gdb) frame 12
(gdb) p *(weak_this_.pn.pi_)
$3 = {_vptr.sp_counted_base = 0x957710 <vtable for boost::detail::sp_counted_impl_p<ClientConnection>+16>, use_count_ = {_M_i = 3}, weak_count_ = {_M_i = 2}}
boost_asio / пример
У меня есть поиск в Интернете, найти https://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/http/server3/connection.cpp
в примере есть примечание, например:
int handle_read:
// If an error occurs then no new asynchronous operations are started. This
// means that all shared_ptr references to the connection object will
// disappear and the object will be destroyed automatically after this
// handler returns. The connection class's destructor closes the socket.
int handle_write:
// No new asynchronous operations are started. This means that all shared_ptr
// references to the connection object will disappear and the object will be
// destroyed automatically after this handler returns. The connection class's
// destructor closes the socket.
почему?
(i) Если в handle_read / handle_write возникает ошибка, не следует ли мне использовать это соединение weak_ptr в других потоках?
(ii) Жизненный цикл класса ClientConnection находится в Asio и контролируется Asio. Что не так в моем коде?
(iii) Я думаю, что он не может использовать stand.post () и connection_lable_ptr, чтобы что-то сделать.Нужно изменить код, как показано ниже?
void ClientConnection::handle_read(const boost::system::error_code& e,
std::size_t bytes_transferred)
{
if (!e)
{
//read data and use it
}
else { //error occurs
//closeSocket();
//boost::shared_ptr<DisConnectCommand> cmd(new DisConnectCommand());
//cmd->setClient(this->weak_from_this()); //here set this connection weak_ptr
//putCmd(cmd); //do something in other thread.
//just close socket
boost::system::error_code error;
mSocket.close(error);
}
}
Я в сети и жду вашей помощи.
спасибо.С наилучшими пожеланиями.