c++ - Boost::asio TCP 服务器——从客户端读取消息

标签 c++ boost tcp boost-asio

我正在尝试使用 boost::asio 创建我的第一个 TCP 服务器。服务器将监听客户端,如果它收到消息“MESSAGE_SEND_A:”,它应该将以下消息发送回客户端:“A|A|A|A|A|A”。如果它收到消息“MESSAGE_SEND_B:”,那么它应该相应地向客户端发送另一条消息:“B|B|B|B|B|B”。

现在,我一直在研究 Boost TCP 服务器教程,它或多或少是清晰的:

编辑:代码根据评论重写

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

 using boost::asio::ip::tcp;

 class tcp_connection : public boost::enable_shared_from_this<tcp_connection>
 {
   public:

   typedef boost::shared_ptr<tcp_connection> pointer;

   static pointer create(boost::asio::io_service& io_service)
   {
      return pointer(new tcp_connection(io_service));
   }

   tcp::socket& socket()
   {
      return socket_;
   }

   void start()
   { 
      // Start reading messages from the server
      start_read();

      if (messageFromClient_ == "MESSAGEA:")
      {
         messageToClient_ = "A|A|A|A|A|A|A|A|A|A";
      }

      else if (messageFromClient_ == "MESSAGEB:")
      {
         messageToClient_ = "B|B|B|B|B|B|B|B|B|B";
      }

      boost::asio::async_write(socket_, boost::asio::buffer(messageToClient_),
          boost::bind(&tcp_connection::handle_write, shared_from_this(),
          boost::asio::placeholders::error,
          boost::asio::placeholders::bytes_transferred));
   }

   private:

   tcp_connection(boost::asio::io_service& io_service) : socket_(io_service)
   {
   }

   // Reading messages from the server
   void start_read()
   {
      // Start an asynchronous operation to read a newline-delimited message.
      // When read, handle_read should kick in
      boost::asio::async_read(socket_, input_buffer_,
          boost::asio::transfer_at_least(1),
          boost::bind(&tcp_connection::handle_read, this,
          boost::asio::placeholders::error));
   }

   // When stream is received, handle the message from the client
   void handle_read(const boost::system::error_code& ec)
   {
      //if (stopped_)
      //  return;

      // Making the message nil every time the function starts. Do I need it???????
      messageFromClient_ = "";

      if (!ec)
      {
          // Extract the newline-delimited message from the buffer.
          std::string line;
          std::istream is(&input_buffer_);
          std::getline(is, line);

          // Empty messages are heartbeats and so ignored.
          if (!line.empty())
          {
              messageFromClient_ = line;
              std::cout << "Received: " << line << "\n";
          }

          start_read();
       }
       else
       {
        std::cout << "Error on receive: " << ec.message() << "\n";
       }
   }

   void handle_write(const boost::system::error_code& /*error*/,
     size_t /*bytes_transferred*/)
   {
   }

   tcp::socket socket_;
   std::string messageToClient_;
   boost::asio::streambuf input_buffer_;
   std::string messageFromClient_;
 };



 class tcp_server
 {
 public:

 tcp_server(boost::asio::io_service& io_service)
   : acceptor_(io_service, tcp::endpoint(tcp::v4(), 7767))
 {
    start_accept();
 }

 private:

 void start_accept()
 {
    tcp_connection::pointer new_connection =
        tcp_connection::create(acceptor_.get_io_service());

    acceptor_.async_accept(new_connection->socket(),
        boost::bind(&tcp_server::handle_accept, this, new_connection,
        boost::asio::placeholders::error));
 }

 void handle_user_read(const boost::system::error_code& err,
    std::size_t bytes_transferred)
 {
 }

 void handle_accept(tcp_connection::pointer new_connection,
    const boost::system::error_code& error)
 {
    if (!error)
    {
       new_connection->start();

       start_accept();
    }
 }

 tcp::acceptor acceptor_;
 };


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

    return 0;
  }

代码在 Qt 上编译得很好,但给了我:

 Error on receive: Operation canceled

每次我尝试从我的客户端 (iPad) 发送消息时。

谢谢!

最佳答案

函数 start() 应该从套接字异步读取,同时在接收到数据时调用 handle_read() 函数。 请查看此示例: http://www.boost.org/doc/libs/1_45_0/doc/html/boost_asio/example/timeouts/async_tcp_client.cpp

关于c++ - Boost::asio TCP 服务器——从客户端读取消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25393001/

相关文章:

c++ - 分离轴定理快把我逼疯了!

c++ - 在没有正则表达式的情况下验证电子邮件地址

c++ - boost::asio UDP 在同一进程中发送/接收

c - 我需要分别接收两个数据包 - linux将它们合并为一个并发送给应用程序

c++ - 在运行时以编程方式检测 CPU 架构

c++ - 是否存在阻止采用D范围的C++语言障碍?

c++ - 提取扫描文档的一部分(个人 ID)——选择哪个库和方法?

c++ - 使用 boost 线程和循环缓冲区挂起的生产者/消费者

C 套接字 : does send wait for recv to end?

c# - WCF 端口不监听