Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/153.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ asio异步读取/异步发送正在绕过它';s处理程序_C++_Boost_Synchronization_Boost Asio - Fatal编程技术网

C++ asio异步读取/异步发送正在绕过它';s处理程序

C++ asio异步读取/异步发送正在绕过它';s处理程序,c++,boost,synchronization,boost-asio,C++,Boost,Synchronization,Boost Asio,我做了一个静态库。我在年创建了这三个类 连接类 #ifndef _CONNECTION_H_ #define _CONNECTION_H_ #include <boost/array.hpp> #include <boost/bind.hpp> #include <boost/shared_ptr.hpp> #include <boost/enable_shared_from_this.hpp> #include <boost/asio.h

我做了一个静态库。我在年创建了这三个类

连接类

#ifndef _CONNECTION_H_
#define _CONNECTION_H_

#include <boost/array.hpp>
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <memory>
#include "ByteBuffer.h"

class Connection: public boost::enable_shared_from_this<Connection>
{
public:
  typedef boost::shared_ptr<Connection> pointer;

  explicit Connection(boost::asio::io_service& io_service);
  virtual ~Connection();
  boost::asio::ip::tcp::socket& socket();

  virtual void OnConnected()=0;
  virtual void Send(std::shared_ptr<uint8_t> buffer, int length);
  void Receive();
  void Disconnect();
  bool connected;
protected:
  virtual void OnReceived(ByteBuffer &b) = 0;

private:
  void handle_Receive(const boost::system::error_code& error, std::size_t bytes_transferred );
  void handle_Send(const boost::system::error_code& error, std::size_t bytes_transferred);

  boost::asio::ip::tcp::socket socket_;
  bool disconnecting;
  boost::array<uint8_t, 1000> read_buffer_;
};

#endif


#include "Connection.h"


Connection::Connection(boost::asio::io_service& io_service)
    :socket_(io_service),disconnecting(false),connected(false){}

Connection::~Connection(){}


boost::asio::ip::tcp::socket& Connection::socket(){
    return socket_;
}

void Connection::Send(std::shared_ptr<uint8_t> buf, int length){
    boost::asio::async_write(socket_,boost::asio::buffer(buf.get(),length),
            boost::bind(&Connection::handle_Send, shared_from_this(), boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred));
}

void Connection::handle_Send(const boost::system::error_code& error, std::size_t bytes_transferred){

}

void Connection::Receive(){
     boost::asio::async_read(socket_,boost::asio::buffer(this->read_buffer_),
        boost::bind(&Connection::handle_Receive, shared_from_this(),boost::asio::placeholders::error,boost::asio::placeholders::bytes_transferred));
}

void Connection::handle_Receive(const boost::system::error_code& error, std::size_t bytes_transferred)
{
  if(!error)
  {
      if(bytes_transferred <=0){
            this->Disconnect();
      }else{
服务器类

#ifndef _SERVER_H_
#define _SERVER_H_

#include "Connection.h"
#include "ConnectionFactory.h"

class Server
{
public:
  Server(boost::asio::io_service& io_service , std::string ip,short port,boost::shared_ptr<ConnectionFactory> factory);
  ~Server();    
private:
  void start_accept();
  void handle_accept(boost::shared_ptr<Connection> conn,const boost::system::error_code& error);

  boost::shared_ptr<ConnectionFactory> m_factory;
  boost::asio::io_service &io_service;
  boost::asio::ip::tcp::acceptor acceptor_;
};

#endif

#include "Server.h"


Server::Server(boost::asio::io_service& io_service,std::string ip,short port,boost::shared_ptr<ConnectionFactory> factory)
    :io_service(io_service), acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_string(ip.data()), port)){

        m_factory = factory;
        start_accept();

        std::cout<<"Socket accepting connections..."<<std::endl;
}

Server::~Server()
{
}


void Server::start_accept(){

    boost::shared_ptr<Connection> conn = m_factory->create(this->io_service);
    acceptor_.async_accept(conn->socket(),
        boost::bind(&Server::handle_accept, this,conn,boost::asio::placeholders::error));

}


void Server::handle_accept(boost::shared_ptr<Connection> conn,const boost::system::error_code& error){
    if (!error){
        std::cout<<"on connected"<<std::endl;
        conn->OnConnected();
        conn->Receive();
        start_accept();
    }
    //conn->Disconnect();
}
\ifndef\u服务器_
#定义服务器_
#包括“Connection.h”
#包括“ConnectionFactory.h”
类服务器
{
公众:
服务器(boost::asio::io_服务和io_服务,std::string ip,短端口,boost::shared_ptr工厂);
~Server();
私人:
void start_accept();
void handle_accept(boost::shared_ptr conn,const boost::system::error_code&error);
boost::共享内存工厂;
boost::asio::io_服务和io_服务;
boost::asio::ip::tcp::acceptor-acceptor;
};
#恩迪夫
#包括“Server.h”
服务器::服务器(boost::asio::io_服务和io_服务,std::string ip,短端口,boost::shared_ptr工厂)
:io_服务(io_服务),接受者(io_服务,boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_字符串(ip.data()),端口)){
m_工厂=工厂;
开始接受();

std::cout
boost::asio::async_read
似乎只在读处理程序达到传递给它的“数据量”时才调用它

引用boost的1.46.0参考:

异步读取

启动异步操作以从流中读取一定数量的数据

因此,作为一种解决方案,如果您希望接收到任意数量的数据,请使用
socket\u.async\u read\u some
而不是
boost::asio::async\u read


另一种解决方案,正如Sam Miller在评论中试图说的那样,您可以添加一个固定大小的标头,其中包含在您应该接收的每个帧之前传入的字节数,读取标头,然后使用先前提取的数字调用
boost::asio::async_read

boost::asio::async_read
似乎调用仅当处理程序达到传递给它的“数据量”时才读取处理程序

引用boost的1.46.0参考:

异步读取

启动异步操作以从流中读取一定数量的数据

因此,作为一种解决方案,如果您希望接收到任意数量的数据,请使用
socket\u.async\u read\u some
而不是
boost::asio::async\u read



另一种解决方案,正如Sam Miller在评论中试图说的那样,你可以添加一个固定大小的头,其中包含在你应该接收的每帧之前传入的字节数,读取头,然后用之前提取的数字调用
boost::asio::async\u read

我不清楚你在哪里遇到问题。什么你现在看到了什么行为?预期的行为是什么?你还应该花一些时间在你的问题中形成完整的句子和正确的大写和标点符号。最后,在外部网站上发布代码通常是不受欢迎的,这会促进链接腐烂。请在你的问题中包含所有相关的代码,以演示问题。@Sam Miller我更新了问题,因为我说过Receive方法应该将数据传递给handel_Receive()方法,以便我可以使用此数据并将其传递给ByteBuffer,但Receive()方法没有调用hnadel_Receive()…@Mixed你做了什么来调试这个问题?服务器期望接收多少字节?客户端发送多少字节?你是如何测试的?@Mixed TCP套接字在数据流上运行,而不是在数据包上运行。同样,你指示async_read期望多少字节?@Mixed不要用数据包来考虑你的通信。TCP sockets在连续的数据流上运行。您需要对服务器和客户端之间发送的消息进行帧处理。实现这一点的一种方法是在发送每条消息之前使用固定长度的报头。该报头将包括消息中预期的字节数,因此您的服务器知道要读取的字节数。我不清楚您在哪里e有问题。你目前看到了什么行为?预期的行为是什么?你还应该花一些时间形成完整的句子,纠正问题中的大写和标点符号。最后,在外部网站上发布代码通常是不受欢迎的,这会导致链接腐烂。请在你的任务中包含所有相关代码Sam Miller我更新了问题,因为我说过Receive方法应该将数据传递给handel_Receive()方法,这样我就可以使用这些数据并将其传递给ByteBuffer,但是Receive()方法没有调用hnadel_Receive()方法…@Mixed你做了什么来调试这个问题?服务器期望接收多少字节?客户端发送多少字节?你是如何测试的?@Mixed TCP套接字在数据流上运行,而不是在数据包上运行。同样,你指示async_read期望多少字节?@Mixed不要用数据包来考虑你的通信。TCP sockets在连续的数据流上运行。您需要对服务器和客户端之间发送的消息设置帧。一种方法是在发送每条消息之前设置一个固定长度的标头。该标头将包括消息中预期的字节数,以便您的服务器知道要读取的字节数。@Khaled Nassar nah我在年更新了它项目,但我忘了在这里更新它,问题是Receive()没有调用handle_Receive()。@Khaled Nassar am CALLING Receive()从服务器class@MixedCoder你的话意味着你已经解决了这个问题,可能想在问题中更新它,或者发布一个带有解决方案的答案?@Khaled Nassar我更新了这个问题,它与调用handle_Receive()无关....@Khaled Nassar nah我在项目中更新了它,但我忘了在这里更新它,问题是Receive()没有调用handle_Receive()。@Khaled Nassar正在调用Receive()从服务器class@MixedCoder你的话意味着你已经解决了这个问题,可能想在问题中更新它,或者发布一个带有解决方案的答案?@Khaled Nassar我更新了这个问题,它与调用handle_Receive()无关。。。。
#pragma once
#include "Connection.h"
class ConnectionFactory
{
public:
    ConnectionFactory(void);
    virtual ~ConnectionFactory(void);

    virtual Connection::pointer create(boost::asio::io_service& io_service) = 0;
};


#include "ConnectionFactory.h"


ConnectionFactory::ConnectionFactory(void)
{
}


ConnectionFactory::~ConnectionFactory(void)
{
}
#ifndef _SERVER_H_
#define _SERVER_H_

#include "Connection.h"
#include "ConnectionFactory.h"

class Server
{
public:
  Server(boost::asio::io_service& io_service , std::string ip,short port,boost::shared_ptr<ConnectionFactory> factory);
  ~Server();    
private:
  void start_accept();
  void handle_accept(boost::shared_ptr<Connection> conn,const boost::system::error_code& error);

  boost::shared_ptr<ConnectionFactory> m_factory;
  boost::asio::io_service &io_service;
  boost::asio::ip::tcp::acceptor acceptor_;
};

#endif

#include "Server.h"


Server::Server(boost::asio::io_service& io_service,std::string ip,short port,boost::shared_ptr<ConnectionFactory> factory)
    :io_service(io_service), acceptor_(io_service, boost::asio::ip::tcp::endpoint(boost::asio::ip::address_v4::from_string(ip.data()), port)){

        m_factory = factory;
        start_accept();

        std::cout<<"Socket accepting connections..."<<std::endl;
}

Server::~Server()
{
}


void Server::start_accept(){

    boost::shared_ptr<Connection> conn = m_factory->create(this->io_service);
    acceptor_.async_accept(conn->socket(),
        boost::bind(&Server::handle_accept, this,conn,boost::asio::placeholders::error));

}


void Server::handle_accept(boost::shared_ptr<Connection> conn,const boost::system::error_code& error){
    if (!error){
        std::cout<<"on connected"<<std::endl;
        conn->OnConnected();
        conn->Receive();
        start_accept();
    }
    //conn->Disconnect();
}
#include <iostream>
#include "auth_proto.h"
#include <Server.h>
#include <ConnectionFactory.h>
#include "AuthConnectionFactory.h"

using namespace std;
int main()
{
    Auth_Setup();
  try
  {
      boost::asio::io_service io_service;
      boost::shared_ptr<ConnectionFactory> fact (new AuthConnectionFactory(io_service));
      Server s(io_service,"5.113.195.156",9959,fact);
      io_service.run();
  }
  catch (std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }

  return 0;
}