连接后连接丢失 - >服务器TCP boost.ASIO

时间:2017-09-27 13:32:45

标签: c++ linux boost tcp server

我做了增强教程:异步TCP日间服务器http://think-async.com/Asio/asio-1.1.1/doc/asio/tutorial/tutdaytime3.html 当我想测试它时,服务器正在运行,所以这很好,但是如果我chan2.setSound(null, null);,客户端得到了服务器的消息,但客户端在之后直接断开连接。

这是我的代码:

nc -C localhost 4242
#include "server.h"
#include "connection.h"

Server::Server(boost::asio::io_service& io_service) : accept(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::tcp::v4(), 4242))
{
  wait_connection();
}

Server::~Server()
{

}

void Server::wait_connection()
{
  std::cout << "wait_connection" << std::endl;
  boost::shared_ptr<Connection> new_connection =
  Connection::start_connection(accept.get_io_service());

  accept.async_accept(new_connection->getSocket(), boost::bind(&Server::callback_accept, this, new_connection, boost::asio::placeholders::error));
}

void Server::callback_accept(boost::shared_ptr<Connection> new_connection, const boost::system::error_code &error)
{
  if (!error)
  {
    new_connection->send_message_to_client();
    wait_connection();
  }
}


Connection::Connection(boost::asio::io_service& io_service) : socket(io_service)
{

}

Connection::~Connection()
{
  std::cout << "destructeur Connection" << std::endl;
}

boost::shared_ptr<Connection> Connection::start_connection(boost::asio::io_service& io_service)
{
  return (boost::shared_ptr<Connection>(new Connection(io_service)));
}

boost::asio::ip::tcp::socket& Connection::getSocket()
{
  return (this->socket);
}

void Connection::send_message_to_client()
{
  message = "Bienvenue!\n";

  boost::asio::async_write(socket, boost::asio::buffer(message), boost::bind(&Connection::callback_send, shared_from_this()));
}

void Connection::callback_send()
{

}

int main()
{
  try {

    boost::asio::io_service io_service;
    Server server(io_service);
    io_service.run();
  }
  catch (std::exception& e) {
    std::cerr << e.what() << std::endl;
  }

  return (0);
}

1 个答案:

答案 0 :(得分:2)

Crux:共享指针用于保持对象存活,直到引用计数达到零。

您可以在此处将消息写入客户端。完成后,您将执行callback_send

boost::asio::async_write(socket, boost::asio::buffer(message),
                         boost::bind(&Connection::callback_send, shared_from_this()));

那我们下一步该做什么?

void Connection::callback_send() {}

喔。那不是......不是很多。所以。没有?

好。几乎没有

这是&#34;没有做某事也是做某事&#34;。通过发布另一个使套接字/连接保持活动的操作,这意味着将释放连接。

因为没有其他东西使shared_ptr保持连接,shared_ptr将删除连接(调用析构函数,你可以看到它,因为它每次都打印destructeur Connection。)

因此。解决办法是什么? 我们不知道。在您说“欢迎&#34;”之后,由您决定要做什么。在大多数情况下,你会想要等待来自客户端的某种消息。这将涉及一些async_read*调用,可以让连接保持活跃状态​​(shared_from_this()再次)。

演示

让我们假设你想继续接收线路,然后你发回相同的线路,反之亦然:

void Connection::callback_send() {
    boost::asio::async_read_until(socket, request, "\n",
                             boost::bind(&Connection::on_request_received, shared_from_this(),
                                 boost::asio::placeholders::error,
                                 boost::asio::placeholders::bytes_transferred));
}

void Connection::on_request_received(boost::system::error_code ec, size_t n) {
    if (ec && !((ec == boost::asio::error::eof) && n))
        std::cout << "Receive error: " << ec.message() << "\n";
    else
    {
        std::cout << "Received request\n";

        {
            std::istream is(&request);
            std::getline(is, message);
        }

        std::reverse(message.begin(), message.end());

        std::cout << "Sending response: " << message << "\n";

        message += '\n';

        if (!ec) boost::asio::async_write(socket, boost::asio::buffer(message),
               boost::bind(&Connection::callback_send, shared_from_this()));
    }
}