Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/145.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++ 通过boost::asio::tcp::ip发送的大型正文_C++_Networking_Boost_Tcp_Boost Asio - Fatal编程技术网

C++ 通过boost::asio::tcp::ip发送的大型正文

C++ 通过boost::asio::tcp::ip发送的大型正文,c++,networking,boost,tcp,boost-asio,C++,Networking,Boost,Tcp,Boost Asio,我的协议非常简单:我发送了一个size\u t,指示身体的大小,然后是身体本身 代码基于,如下所示: class tcp_conn : public std::enable_shared_from_this<tcp_conn>, private boost::noncopyable { public: tcp_conn(ba::io_service& io_service); void st

我的协议非常简单:我发送了一个
size\u t
,指示身体的大小,然后是身体本身

代码基于,如下所示:

class tcp_conn : 
        public std::enable_shared_from_this<tcp_conn>, 
        private boost::noncopyable 
    {
    public:
        tcp_conn(ba::io_service& io_service);
        void start();
        void stop();

        tcp::socket& socket();

    private:
        void handle_read_header(const error_code& e, std::size_t bytes_transferred);
        void handle_read(const error_code& e, std::size_t bytes_transferred);

        ba::streambuf::mutable_buffers_type buffer_wrapper_;
        ba::streambuf buffer_;
        std::size_t buffer_size_;
        tcp::socket socket_;

};
类tcp\u连接:
public std::从\u this启用\u共享\u,
私有boost::不可复制
{
公众:
tcp_连接(ba::io_服务和io_服务);
void start();
无效停止();
tcp::socket和socket();
私人:
无效句柄\u读取\u头(常量错误\u代码&e,标准::大小\u t字节\u传输);
无效句柄读取(常量错误代码和e,标准::大小字节传输);
ba::streambuf::可变缓冲区\类型缓冲区\包装器\包装器;
ba::streambuf缓冲区;
std::size\u t buffer\u size\u;
tcp::socket-socket;
};
具体实施如下:

void tcp_conn::start() {
    socket_.async_read_some(
        ba::buffer(&buffer_size_, sizeof(buffer_size_)),
        boost::bind(
          &tcp_conn::handle_read_header,
          this,
          ba::placeholders::error,
          ba::placeholders::bytes_transferred
          )
        );
}

void tcp_conn::handle_read_header(const boost::system::error_code& e, std::size_t bytes_transferred){
    if(!e) {
        buffer_wrapper_ =  buffer_.prepare(buffer_size_);

        socket_.async_read_some(
            ba::buffer(buffer_wrapper_),
            boost::bind(
              &tcp_conn::handle_read,
              this,
              ba::placeholders::error,
              ba::placeholders::bytes_transferred
              )
            ); 

    } else {
        //stop connection
    }
}


void tcp_conn::handle_read(const boost::system::error_code& e, std::size_t bytes_transferred)   {
    if (!e ) {
        buffer_.commit(bytes_transferred);

        if(buffer_.size() == buffer_size_) {
            std::cout << "WHOLE BODY TRANSFERED NOW" << std::endl;
            //has all data in buffer, handle it.
        }
        else {
            std::cout << "NOT WHOLE BODY TRANSFERED, still got "<< (buffer_size_ - bytes_transferred) << " to go" << std::endl;
            socket_.async_read_some(
                ba::buffer(buffer_wrapper_),
                boost::bind(
                  &tcp_conn::handle_read,
                  this,
                  ba::placeholders::error,
                  ba::placeholders::bytes_transferred
                  )
                ); 
        }


    }
    else {
        //handle error
    }   
}
void tcp_conn::start(){
套接字异步读取(
ba::buffer(&buffer_size,sizeof(buffer_size)),
boost::bind(
&tcp\u连接::句柄\u读取\u头,
这
ba::占位符::错误,
ba::占位符::已传输的字节数
)
);
}
无效tcp连接::句柄\u读取\u头(常量boost::系统::错误\u代码和e,std::大小\u t字节\u传输){
如果(!e){
缓冲区包装器=缓冲区准备(缓冲区大小);
套接字异步读取(
ba::缓冲区(缓冲区包装器),
boost::bind(
&tcp\u连接::句柄\u读取,
这
ba::占位符::错误,
ba::占位符::已传输的字节数
)
); 
}否则{
//停止连接
}
}
无效tcp连接::句柄读取(常量boost::系统::错误代码和e,std::大小\u t字节\u传输){
如果(!e){
缓冲区提交(传输的字节);
if(缓冲区大小()==缓冲区大小){
std::cout
缓冲区.提交()
使
准备()
的结果无效,如下所述:

实际上,您不必手动准备缓冲区并链接
async\u read\u some()
,只需将适当的无助手函数与
streambuf
和完成条件一起使用即可:

asio::async_read(
   socket_,
   buffer_, 
   asio::transfer_exactly(buffer_size_),
   boost::bind(&tcp_conn::handle_read, this, _1, _2)
);

通过这种方式,
handle\u read
会在您获取整个消息正文或发生错误时被调用。

嘿,谢谢。我只是用一个复杂的手动缓冲区更新来实现它。您的答案几乎是完美的,但是您能为上述代码提供所有名称空间前缀吗(在中定义的_1、_2、transfer\u等在哪里?)@Queequeg
transfer\u恰好位于
asio
名称空间中,
\u 1
\u 2
绑定占位符位于全局名称空间中(您可以继续使用asio占位符,就像您的问题一样)。非常感谢您,它现在更干净了!它确实有效:)