2011-06-03 114 views
1

我做了一个静态库。我在boost :: asio async_read/async_send绕过它的处理程序

连接类

#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{ 

字节缓冲区b创建此三类((STD :: shared_ptr的)这 - > read_buffer_.data(),这 - > read_buffer_.size()); this-> OnReceived(b); 这 - >接收();}}
}

void Connection::Disconnect() 
{ 
    if (!disconnecting) { 
     boost::system::error_code ec; 
     socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_send,ec); 
     socket_.close(ec); 
     disconnecting = true; 
     std::cout<<"disconnected"<<std::endl; 
    } 
} 

ConnectionFactory类

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

和我从静态-LIB drevid和使用该类和它的工作完美

在我的main.cpp

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

我真的不明白什么是错在这里,当谈到接收()函数,它接收来自客户端的数据,但它不调用handle_Receive()方法,所以我可以使用这个数据,我正在等待的行为,它应该调用handle_Receive(),所以我可以将数据传递给ByteBuffer并使用它,但这不会发生......

+0

我不明白你在哪里有问题。你目前看到什么行为?预期的行为是什么?你还应该花一些时间来形成完整的句子,并在你的问题中修正大写和标点符号。最后,在外部网站上张贴代码通常是不受欢迎的,它促进了链接腐烂。请在您的问题中包含所有相关代码以证明问题。 – 2011-06-03 01:25:20

+0

@Sam Miller我更新了问题,正如我所说的,Receive方法应该将数据传递给handel_Recive()方法,以便我可以使用此数据并将其传递给ByteBuffer,但Recevie()方法不会调用hnadel_Receive ... – Abanoub 2011-06-03 01:44:23

+0

@Mixed你做了什么来调试问题?服务器希望接收多少个字节?客户端发送多少个字节?你如何测试这个? – 2011-06-03 01:49:21

回答

4

boost::asio::async_read似乎打电话给只有在读取处理程序达到传递给它的“数据量”时才执行读取处理程序。

引用升压的1.46.0参考:

async_read

启动一个异步操作以从流读出的数据的一个一定量。

所以,作为一个解决方案,使用socket_.async_read_some代替boost::asio::async_read如果你想被告知接收数据的任意量。

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

+0

@Khaled Nassar nah我在项目中更新它,但我忘了在这里更新它,问题是Receive()不是CALLING handle_Receive()。 – Abanoub 2011-06-03 04:51:58

+0

@Khaled Nassar从服务器类调用Receive() – Abanoub 2011-06-03 04:56:28

+0

@MixedCoder你的话意味着你固定了这个问题,可能想在问题中更新它,或者用解决方案发布一个答案? – 2011-06-03 05:06:58

相关问题