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...@gmail.com> Date: Dec 4, 1:44 am Subject: boost asio async_read_some To: BOOST Archives _______________________________________________ Boost-users mailing list Boost-us...@lists.boost.orghttp://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 -