wacky async_read?_write behavior!

Hi, I am trying to do a simple POP3S client. I am using the boost::asio sockets and SSL wrapper. Somehow, the output from the sock read is directed to the input of the sock write. Any idea? The code snippet is below, but here is the output of my program first (I replaced the IP with x's) -bash# ./main 209.85.199.111 995 foo.bar@gmail.com pass_in_plain_text Got RES (66) bytes +OK Gpop ready for requests from xxx.xxx.xxx.xxx c20pf1156691rvf.3 Sent REQ: APOP foo.bar@gmail.com pass_in_plain_text Got RES (36) bytes -ERR bad command c20pf1156691rvf.3 Sent REQ: STAT Read failed: End of file Exception: End of file and here is the code snippet that produced this input enum { max_length = 8192 }; class client { public: client(boost::asio::io_service& io_service, boost::asio::ssl::context& context, boost::asio::ip::tcp::endpoint& endpoint) : socket_(io_service, context) { //connect to the pop3 server socket_.lowest_layer().async_connect(endpoint, boost::bind(&client::handle_connect, this, boost::asio::placeholders::error)); } ~client() { socket_.lowest_layer().close(); } void handle_connect(const boost::system::error_code& error) { if (!error) { //do the SSL handshake socket_.async_handshake(boost::asio::ssl::stream_base::client, boost::bind(&client::handle_handshake, this, boost::asio::placeholders::error)); } else { std::cerr << "Connection failed: " << error << "\n"; boost::asio::detail::throw_error(error); } } void handle_handshake(const boost::system::error_code& error) { if (error) { std::cerr << "SSL Handshaking failed: " << error << "\n"; boost::asio::detail::throw_error(error); } } void write(std::string buffer) { str_req=buffer; boost::asio::async_write(socket_, boost::asio::buffer(str_req), boost::bind(&client::handle_write, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); } void handle_write(const boost::system::error_code& error, size_t bytes) { if (!error) { std::cout << "Sent REQ: " << str_req <<std::endl; try{ boost::asio::async_read_until(socket_, buff_, "\r\n", boost::bind(&client::handle_read_until, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); }catch(const boost::system::system_error &err){ std::cerr << " code: " << err.code().value() << " :" << err.code().message() << std::endl; } } else { std::cerr << "Write failed: " << error.message() << "\n"; boost::asio::detail::throw_error(error); } } void read() { try{ boost::asio::async_read_until(socket_, buff_, "\r\n", boost::bind(&client::handle_read_until, this, boost::asio::placeholders::error, boost::asio::placeholders::bytes_transferred)); }catch(const boost::system::system_error &err){ std::cerr << " code: " << err.code().value() << " :" << err.code().message() << std::endl; } } void handle_read_until(const boost::system::error_code& error, size_t bytes_transferred) { if (!error) { std::cout << "Got RES (" << bytes_transferred<<") bytes\n"; std::cout << &buff_; std::cout << "\n"; } else { std::cout << "Read failed: " << error.message() << "\n"; boost::asio::detail::throw_error(error); } } private: boost::asio::ssl::stream<boost::asio::ip::tcp::socket> socket_; boost::asio::streambuf buff_; //for receiving std::string str_req; //for sending }; int main(int argc, char* argv[]) { try { if (argc != 5) { std::cerr << "Usage: " << argv[0] << " <host> <port> <user> <pass>\n"; return 1; } boost::asio::io_service io_service; boost::asio::ssl::context ctx(io_service, boost::asio::ssl::context::sslv23); ctx.set_verify_mode(boost::asio::ssl::context::verify_none); boost::asio::ip::tcp::endpoint endpoint( boost::asio::ip::address::from_string(argv[1]), atoi(argv[2])); client c(io_service, ctx, endpoint); io_service.run(); //should execute till handshake completes //read the pop3 greeting io_service.reset(); io_service.post(boost::bind(&client::read,&c)); io_service.run(); //send the authentication command std::string str_cmd="APOP " + std::string(argv[3]) + " " + std::string(argv[4]) +"\r\n"; io_service.reset(); io_service.post(boost::bind(&client::write,&c,str_cmd)); io_service.run(); //get how many messages are in the inbox str_cmd="STAT\r\n"; io_service.reset(); io_service.post(boost::bind(&client::write,&c,str_cmd)); io_service.run(); //quit the pop3 session str_cmd="QUIT\r\n"; io_service.reset(); io_service.post(boost::bind(&client::write,&c,str_cmd)); io_service.run(); } catch (std::exception& e) { std::cerr << "Exception: " << e.what() << "\n"; } return 0; }
participants (1)
-
Abu Amar