|
Boost Users : |
Subject: Re: [Boost-users] boost asio async_read_some
From: Chris Freehill (cfreehill_at_[hidden])
Date: 2008-12-07 19:25:43
Igor,
Thanks for the response. I've been out for a few days, so I haven't
been able to reply. Here is a self-contained example that illustrates
the problem. This example creates a echo server thread that should
echo back to the caller anything the caller sends to the thread. (Note
that I have a windows Sleep() in there.) The server thread appears to
do what I expect. The client thread works until the call to
async_read_some(). The call returns, but I never hit the breakpoint I
set in my handler, nor do I see any output from the handler.
Igor, or anyone, please have a look...
Thanks,
Chris
=============================================START==================================================
#include <string>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/smart_ptr.hpp>
#include <boost/thread.hpp>
const static unsigned int cMaxLength = 512;
static const std::string cStopEchoCommand("STOP_ECHO");
static boost::asio::io_service ioService; //needs to have the same
life span as socket, or longer
static boost::asio::ip::tcp::resolver lResolver(ioService);
//-------------------------------------------------------------------------------------------------
static int doConnect(std::string& ipAddress, std::string& portNumber,
boost::shared_ptr<boost::asio::ip::tcp::socket>& inOutSocket)
{
using boost::asio::ip::tcp;
try
{
tcp::resolver::query query(tcp::v4(), ipAddress.c_str(), portNumber.c_str());
tcp::resolver::iterator endpoint_iterator = lResolver.resolve(query);
tcp::resolver::iterator end;
if (inOutSocket == NULL)
{
boost::shared_ptr<tcp::socket> tmpSocketPtr(new
tcp::socket(ioService));
inOutSocket = tmpSocketPtr;
}
boost::system::error_code error = boost::asio::error::host_not_found;
while (error && endpoint_iterator != end)
{
inOutSocket->close();
inOutSocket->connect(*endpoint_iterator++, error);
}
if (error) {
return -1;
}
}
catch(...)
{
return -1;
}
return 0;
}
//Server routine
static void session(unsigned int port)
{
using boost::asio::ip::tcp;
boost::asio::io_service io_service;
tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), port));
tcp::socket sock(io_service);
try
{
bool done = false;
a.accept(sock);
for (;;)
{
char data[cMaxLength];
boost::system::error_code error;
size_t length = sock.read_some(boost::asio::buffer(data, cMaxLength), error);
if (error == boost::asio::error::eof)
{
// done, stop echoing, wait for another connection
break;
}
else if (error)
{
std::cerr << "Error while receiving: " <<
boost::system::system_error(error).what() << "\n";
// TODO report failure
break; // closing.
}
else if (length == cStopEchoCommand.length())
{
//See if it's time to end
if (cStopEchoCommand.compare(0, cStopEchoCommand.length(), data))
{
break;
}
}
else
{
//boost::asio::write(sock, boost::asio::buffer(data, length));
int bytesWritten = sock.write_some(boost::asio::buffer(data, length));
if (bytesWritten == 0)
{
std::cerr << "Error while writing to socket: " <<
boost::system::system_error(error).what() << "\n";
}
}
}
}
catch (std::exception& e)
{
// TODO report failure
std::cerr << "Exception in thread: " << e.what() << "\n";
}
}
class TestClass
{
public:
TestClass(std::string ipAddress, std::string
port):mIPAddress(ipAddress), mPort(port)
{}
void PollReadhandler(const boost::system::error_code& error, size_t
bytes_transferred)
{
mDataReadFromPoll = true;
boost::system::error_code e;
std::cout << "DELETE ME; PollReadhandler called()" << "\n";
}
void testTCPIP()
{
using boost::asio::ip::tcp;
// Start an separate thread which echoes all trafic to the port.
std::istringstream i(mPort);
unsigned int port;
i >> port;
mDataReadFromPoll = false;
boost::thread echoTcpServer(boost::bind(session, port));
boost::shared_ptr<tcp::socket> socketPtr;
int ret = doConnect(mIPAddress, mPort, socketPtr);
if (ret)
{
std::cerr << "Failed to get connection" << std::endl;
return;
}
//-------------------------------------------------------------------------------------------------
// test sync. read
char buffer[512];
unsigned int bytesRead;
std::string test1Str("Test 1");
std::size_t len =
socketPtr->write_some(boost::asio::buffer(test1Str.c_str(),
test1Str.length()));
Sleep(1000); //Windows
try
{
int readError = 0;
std::vector<unsigned char> readVectorBuffer(32);
//unsigned char readVectorBuffer[512];
boost::system::error_code e;
//unsigned int amtRead =
socketPtr->read_some(boost::asio::buffer(readVectorBuffer, 512), e);
unsigned int amtRead =
socketPtr->read_some(boost::asio::buffer(readVectorBuffer, 32), e);
if (amtRead != test1Str.length())
{
std::cerr << "read_some read an unexpected number of bytes" << std::endl;
return;
}
std::string s(readVectorBuffer.begin(),readVectorBuffer.end());
std::cout << "read_some returned:" << s << std::endl;
}
catch (...)
{
std::cerr << "Problem with read_some" << std::endl;
}
//-------------------------------------------------------------------------------------------------
// test async. read
std::string test2Str("Test 2");
len = socketPtr->write_some(boost::asio::buffer(test2Str.c_str(),
test2Str.length()));
Sleep(1000);
//Poll
while (!mDataReadFromPoll)
{
socketPtr->async_read_some(boost::asio::buffer(buffer, 512),
boost::bind(&TestClass::PollReadhandler, this,
boost::asio::placeholders::error,
boost::asio::placeholders::bytes_transferred));
Sleep(1000);
}
//NEVER REACHES HERE
mDataReadFromPoll = false;
len = socketPtr->write_some(boost::asio::buffer(cStopEchoCommand.c_str(),
cStopEchoCommand.length()));
// Wait until the server thread is finished.
echoTcpServer.join();
}
//-------------------------------------------------------------------------------------------------
private:
std::string mIPAddress;
std::string mPort;
bool mDataReadFromPoll;
};
int main()
{
TestClass testCase("127.0.0.1", "2222");
testCase.testTCPIP();
}
=============================================END====================================================
---------- Forwarded message ----------
From: "Igor R" <boost.li..._at_[hidden]>
Date: Dec 4, 1:44 am
Subject: boost asio async_read_some
To: BOOST Archives
_______________________________________________
Boost-users mailing list
Boost-us..._at_[hidden]http://lists.boost.org/mailman/listinfo.cgi/boost-users
> Here's a simplified version of my call and handler:
> unsigned char tmpBuffer[512]; //global
> void MyClass::handler(const boost::system::error_code& error, size_t
> bytes_transferred)
> {
> boost::system::error_code e;
> std::cerr << "handler called()" << "\n";
> }
> void MyClass::test()
> {
> ...
> socketPtr->async_read_some(boost::asio::buffer(tmpBuffer, 512),
> boost::bind(&MyClass::handler, this,
> boost::asio::placeholders::error,
> boost::asio::placeholders::bytes_transferred));
> }
> Can anyone give me any idea as to how I can get my handler to be called?
Could you please provide some code-excerpt that should compile and work?
I.e. code that contains socket initialization, io_service run and your
object creation - because the mistake is probably somewhere at those points.
> Invocation of the handler will be performed in a
> manner equivalent to using boost::asio::io_service::post()." I'm not
> sure exactly what this means...what is this equivalent manner that is
> mentioned?
It means that the handler would be invoked in one of the threads that run
the io_service object used by the socked.- Hide quoted text -
- Show quoted text -
Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net