加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 当服务器执行asio :: write操作时客户端断开连接时,Boost T

发布时间:2020-12-16 07:13:15 所属栏目:百科 来源:网络整理
导读:只是为了测试我的服务器,我已经从我的客户端使用for循环创建了100个请求,而我的服务器正在为第N个请求写响应,我故意从客户端按下控制c,就是这样.服务器停止并且没有响应,虽然我尝试使用新连接连接它,任何人都可以建议我如何使我的服务器稳定并免受这种中断.
只是为了测试我的服务器,我已经从我的客户端使用for循环创建了100个请求,而我的服务器正在为第N个请求写响应,我故意从客户端按下控制c,就是这样.服务器停止并且没有响应,虽然我尝试使用新连接连接它,任何人都可以建议我如何使我的服务器稳定并免受这种中断.
这是我的服务器:

class tcp_server
 {
 public:

 tcp_server(boost::asio::io_service& io_service)
   : acceptor_(io_service,tcp::endpoint(tcp::v4(),2020))
 {
    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_;
 };

这是我的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();

   }

   public:

   tcp_connection(boost::asio::io_service& io_service) : socket_(io_service),timer_(io_service),io(io_service),timer2_(io_service)
   {
          }


   // Reading messages from the server
   void start_read()
   {
          boost::asio::async_read(socket_,input_buffer_,boost::asio::transfer_at_least(1),boost::bind(&tcp_connection::handle_read,shared_from_this(),boost::asio::placeholders::error));
          timer_.expires_from_now(boost::posix_time::seconds(120));
          timer_.async_wait(boost::bind(&tcp_connection::close,shared_from_this()));

   }
   void close()
  {
    cout<<"I didn't hear the client yet:closing the socket......"<<endl;
    socket_.close();
  }


   // When stream is received,handle the message from the client
  int handle_read(const boost::system::error_code& ec)
   {

      if (!ec)
      {

          std::istream is(&input_buffer_);
          std::string line;
          std::getline(is,line);
          messageFromClient_+=line;
          messageFromClient_.erase(std::remove(messageFromClient_.begin(),messageFromClient_.end(),'n'),messageFromClient_.end());
          std::size_t found = messageFromClient_.find('');
          if(found==std::string::npos)
          {
          boost::asio::async_read(socket_,boost::asio::placeholders::error));
          }
          else{
            performmaj();--my logic never mind.
            std::cout << "Request: "<<i<<" is on process......"<<"n";--mylogic 
            boost::asio::ip::tcp::no_delay option(true);
            socket_.set_option(option);
            write();
            messageToClient_="";--my logic.
            boost::system::error_code tc;
            socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_send,tc);
            }
            std::cout << "Request: "<<i<<" completed"<<"n";
            ++i;
(boost::asio::io_service io);
          }else
       {
        std::cout << "Error on receive: " << ec.message() << "n";
       }

   }

void write()
{
    try{
    boost::asio::write(socket_,boost::asio::buffer(messageToClient_),boost::asio::transfer_at_least(messageToClient_.size()));
    }catch(exception e)
    {
        cout<<e.what()<<endl;
        socket_.close();
        io.run();
    }

}

请查看我使用async_write的下面的代码;请注意我有意写的字符串大小:11279204.但是在下面的代码中使用async_write让我的客户端接收更多部分但不完整的meaasage.

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

   }

   public:

   tcp_connection(boost::asio::io_service& io_service) : socket_(io_service),timer2_(io_service)
   {
       //io=io_service;
   }


   // Reading messages from the server
   void start_read()
   {
          boost::asio::async_read(socket_,boost::asio::placeholders::error));
          }
          else{
            performmaj();
            cout<<messageToClient_.size()<<endl;--11279204
              try{
            boost::asio::async_write(socket_,boost::asio::buffer(messageToClient_.data(),messageToClient_.size()),// boost::asio::transfer_at_least(messageToClient_.size()),boost::bind(&tcp_connection::handle_write,boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
            }catch(exception e)
            {
                Shutdown();
            }
            }
            std::cout << "Request: "<<i<<" completed"<<"n";
            ++i;
            return 0;

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

   }

 void Shutdown()
  {
    try {
      socket_.shutdown(socket_.shutdown_both);
      socket_.close();
    } catch (std::exception &e)
    {
      std::cout << "Error Closing Socket" << e.what() << std::endl;
    }
  }

void performmaj()
 {
    std::size_t found = messageFromClient_.find('');
    if (found!=std::string::npos)
    {
            std::cout << "Request: "<<i<<" Recieved"<<"n";
            std::cout << "Request: "<<i<<" is on process......"<<"n";
            if (messageFromClient_.size () > 0) messageFromClient_.resize (messageFromClient_.size () - 1);
            messageToClient_=test(messageFromClient_);
            messageFromClient_="";
            messageToClient_.erase(std::remove(messageToClient_.begin(),messageToClient_.end(),messageToClient_.end());

     }

 }

   void handle_write(const boost::system::error_code& ec,size_t bytes_transferred)
   {
            boost::asio::async_write(socket_,bytes_transferred),// boost::asio::transfer_at_least(bytes_transferred),bytes_transferred));
            boost::system::error_code tc;
            socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_send,tc);


   }
   tcp::socket socket_;
   std::string messageToClient_;
   boost::asio::streambuf input_buffer_;
   std::string messageFromClient_;
   boost::asio::io_service& io;
   boost::asio::deadline_timer timer_,timer2_;

 };

上面async_write的不可预知的行为导致我使用asio :: write.

解决方法

boost :: asio :: write()会阻塞,直到写入数据或抛出异常. write()函数捕获异常,关闭套接字并返回,但不表示套接字已关闭.然后在关闭的套接字上调用shutdown.创建关机功能.在write()中捕获丢弃异常错误但等待在Write()调用后调用Shutdown.您的逻辑总是在写入好或坏时调用Shutdown().也不要调用io.run().您的io_service()已在运行.

Shutdown()
  {
    try {
      socket_.shutdown(socket_.shutdown_both);
      socket_->close();
    } catch (std::exception &e)
    {
      std::cout << "Error Closing Socket" << e.what() << std::endl;
    }
  }

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读