Reputation: 3809
I am attempting to convert the return value of the function boost::asio::async_read
to an int
in order to see if I've received any data:
int recvlen = boost::asio::async_read (
socket_,
boost::asio::buffer((char*)buffer, 1000),
boost::bind(&Connection::Receive, this, boost::asio::placeholders::error)
);
Here is that statement in the context of the rest of my code, which does not compile:
.h file:
#ifndef _CONNECTION_H_
#define _CONNECTION_H_
#include <boost/bind.hpp>
#include <boost/shared_ptr.hpp>
#include <boost/enable_shared_from_this.hpp>
#include <boost/asio.hpp>
#include <stdint.h>
class Connection
{
public:
Connection(boost::asio::io_service& io_service);
~Connection();
boost::asio::ip::tcp::socket& socket() {return socket_;}
void Send(uint8_t* buffer, int length);
bool Receive();
protected:
virtual void OnReceived(uint8_t* buffer, int len) = 0;
private:
boost::asio::ip::tcp::socket socket_;
};
#endif
.cpp file:
#include "Connection.h"
Connection::Connection(boost::asio::io_service& io_service)
: socket_(io_service) {}
Connection::~Connection() {}
void Connection::Send(uint8_t* buffer,int length) {
boost::asio::async_write (
socket_,
boost::asio::buffer(buffer, length),
boost::bind(&Connection::Send, this,boost::asio::placeholders::error)
);
}
bool Connection::Receive(){
uint8_t* buffer = new uint8_t[1000];
//Conversion excerpt
int recvlen = boost::asio::async_read (
socket_,
boost::asio::buffer((char*)buffer, 1000),
boost::bind(&Connection::Receive, this, boost::asio::placeholders::error)
);
if (recvlen <= 0) {
delete[] buffer;
return false;
}
this->OnReceived(buffer, recvlen);
delete[] buffer;
return true;
}
These are the errors this code produces in Visual C++:
error C2825: 'F': must be a class or namespace when followed by '::' e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69
error C2039: 'result_type' : is not a member of '`global namespace'' e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69
error C2146: syntax error : missing ';' before identifier 'type' e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69
error C2208: 'boost::_bi::type' : no members defined using this type e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69
error C1903: unable to recover from previous error(s); stopping compilation e:\boost_1_46_1\boost_1_46_1\boost\bind\bind.hpp 69
IntelliSense: a value of type "void" cannot be used to initialize an entity of type "int" d:\c++\ugs\common\connection.cpp 18
IntelliSense: the #endif for this directive is missing d:\c++\ugs\common\connection.h 1
IntelliSense: this declaration has no storage class or type specifier d:\c++\ugs\common\connection.h 26
How can I accomplish what I'm trying to do? In addition, what do these errors mean and how can I fix them?
Upvotes: 4
Views: 4798
Reputation: 3635
async_read
does not return the number of bytes read. It performs the read in the background, asynchronously. The number of bytes is passed to the completion handler. The completion handler is invoked by ASIO when the read completes. You pass the completion handler into async_read
. async_read
is a template that accepts any function object as the handler. In your case, you passed the output of the bind statement.
There are good examples in the boost documentation, but here are two quick solutions.
You could use the synchronous boost::asio::read function instead of boost::asio::async_read.
int recvlen = boost::asio::read(socket_,boost::asio::buffer((char*)buffer, 1000));
Or, you could add a new function:
void HandleReceive(boost::system::error_code &error, std::size_t recvlen)
{
if (!error && error != boost::asio::error::message_length) {
this->OnReceived(buffer, recvlen);
delete [] buffer;
} // else ERROR!!!
}
And call async_read like
boost::asio::async_read(socket_,boost::asio::buffer((char*)buffer, 1000),
boost::bind(&Connection::HandleReceive, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
You will have to make buffer
a class variable for the asynchronous example to work, but you may want to come up with a better way to manage the memory. Also, you will have to do something to deal with lifetime issues of the Connection
class. Check the ASIO examples for a better developed example.
Upvotes: 3