简体   繁体   English

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

[英]Connection lost just after connection -> Server TCP boost.ASIO

I did the boost tutorial : An asynchronous TCP daytime server http://think-async.com/Asio/asio-1.1.1/doc/asio/tutorial/tutdaytime3.html When I want to test it, the server is running so that's good but if I do nc -C localhost 4242 the client got the message of the server but the client is directly disconnected after. 我做了增强教程:异步TCP日间服务器http://think-async.com/Asio/asio-1.1.1/doc/asio/tutorial/tutdaytime3.html当我要对其进行测试时,服务器正在运行很好,但是如果我执行nc -C localhost 4242 ,客户端会收到服务器的消息,但是客户端之后会直接断开连接。

Here my code : 这是我的代码:

#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);
}

#ifndef SERVER_H
#define SERVER_H

#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include "connection.h"

class Server {
private:
  boost::asio::ip::tcp::acceptor accept;

public:
  Server (boost::asio::io_service&);
 ~Server ();

  void wait_connection();
  void callback_accept(boost::shared_ptr<Connection> new_connection, const boost::system::error_code& error);

};

#endif /* end of include guard: SERVER_H */


#ifndef CONNECTION_H
#define CONNECTION_H

#include <iostream>
#include <string>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>

class Connection : public boost::enable_shared_from_this<Connection>
{
private:
  boost::asio::ip::tcp::socket socket;
  std::string message;
public:
  Connection (boost::asio::io_service&);
  ~Connection ();

  static boost::shared_ptr<Connection> start_connection(boost::asio::io_service&);
  boost::asio::ip::tcp::socket& getSocket();
  void send_message_to_client();
  void callback_send();
};

#endif /* end of include guard: CONNECTION_H */

Crux: Shared pointers employ keep the object alive until the reference count reaches zero. 关键:共享指针的使用使对象保持活动状态,直到引用计数达到零为止。

You write the message to the client here. 您在此处将消息写入客户端。 When it's complete, you will execute callback_send : 完成后,您将执行callback_send

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

So what do we do next? 那么我们下一步该怎么做?

void Connection::callback_send() {}

Oh. 哦。 That's... not a lot. 那不是很多。 So. 所以。 Nothing? 没有?

Well. 好。 Almost nothing . 几乎什么都没有

It's a case of "not doing something is also doing something". 这是“不做某事也在做某事”的情况。 By not posting another operation that keeps the socket/connection alive, this means that the connection is going to be released. 通过发布使套接字/连接保持活动状态的其他操作,这意味着将释放连接。

Because nothing else keeps the shared_ptr to the connection, shared_ptr will delete the connection (invoking the destructor, which you could see because it prints destructeur Connection every time). 因为没有其他方法可以使shared_ptr保持连接状态,所以shared_ptr会删除该连接(调用析构函数,您可以看到该析构函数,因为它每次都会打印destructeur Connection )。

So. 所以。 What is the solution? 解决办法是什么? We Don't Know . 我们不知道 It's up to you what you want to do after you said "welcome". 说“欢迎”后,您要做什么。 In most likely-hood you will want to wait for some kind of message from the client. 在最有可能的情况下,您将要等待来自客户端的某种消息。 This would involve some async_read* call which happily keeps the connection alive ( shared_from_this() again). 这将涉及一些async_read*调用,该调用可以使连接保持活动状态(再次async_read* shared_from_this() )。

Demo 演示

Let's assume you want to keep receiving lines, and you send the same lines back, reversed: 假设您想继续接收线路,并且将相同的线路发回,但顺序相反:

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()));
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM