[asio] wacky behavior in async_write/async_read

Hi, I am trying to code a simple POP3S client. I am using the boost::asio sockets and SSL wrapper. Somehow, the output from the async_read_util is directed to the input of the async_write. Not sure if the issue is the memory or the order of calls. 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 #include <cstdio> #include <cstdlib> #include <unistd.h> #include <iostream> #include <boost/bind.hpp> #include <boost/asio.hpp> #include <boost/asio/ssl.hpp> #include <boost/asio/detail/throw_error.hpp> 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; } -- View this message in context: http://www.nabble.com/-asio--wacky-behavior-in-async_write-async_read-tp1909... Sent from the Boost - Users mailing list archive at Nabble.com.
participants (1)
-
n0vicd_c0der