码迷,mamicode.com
首页 > 其他好文 > 详细

boost_asio学习笔记[2] - 客户端异步通讯

时间:2015-06-22 06:31:59      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:

使用boost::asio实现客户端的异步通讯访问pop3服务器。


#include <iostream>
#include <boost/asio.hpp>
#include <boost/bind.hpp>

using namespace std;
using boost::asio::ip::tcp;

#define MAIL_SERVER "pop3.m.com" // 邮件服务器域名

// pop3命令
#define CMD_USER  "user myuser\n"
#define CMD_PASS  "pass mypass\n"
#define CMD_QUIT  "quit\n"

// 接收缓存
#define RECV_BUFFER_SIZE 1024

// 异步socket事件处理类
class async_socket_handler
{
private:
    tcp::socket &m_sock;  // boost tcp socket
    string m_status;      // 执行状态
    char   m_buffer_1[RECV_BUFFER_SIZE];  // 消息接收缓存

public:
    async_socket_handler(tcp::socket &sock) : m_sock(sock), m_status("closed")
    {
        return;
    }

    // 当连接完成后,执行该方法
    void on_connected(const boost::system::error_code& error)
    {
        if ( error == 0 ) {
            // 连接成功,打印消息,
            cout<<"info: connection has been established"<<endl;
            m_status = "connected";

            // 接收服务器欢迎消息,消息收到后,触发on_message_arrival消息执行
            m_sock.async_read_some(boost::asio::buffer(m_buffer_1, RECV_BUFFER_SIZE),
                                   boost::bind(&async_socket_handler::on_message_arrival,
                                               this,
                                               boost::asio::placeholders::error,
                                               boost::asio::placeholders::bytes_transferred));
        } else {
            cout<<"error: failed to connect remote: "<<error<<endl;
        }
    } // end of on_connected

    // 命令消息发送异步事件处理方法,当命令发送完成后,将执行该方法。
    void on_message_sent(const boost::system::error_code& error, size_t size)
    {
        if ( error == 0 ) {
            cout<<"info: "<<m_status<<",  "<<size<<" bytes sent"<<endl;

            // 命令消息发送成功后,立即准备收消息,消息收到后,触发on_message_arrival消息执行
            m_sock.async_read_some(boost::asio::buffer(m_buffer_1, RECV_BUFFER_SIZE),
                                   boost::bind(&async_socket_handler::on_message_arrival,
                                   this,
                                   boost::asio::placeholders::error,
                                   boost::asio::placeholders::bytes_transferred));
        } else {
            cout<<"error: "<<m_status<<" failed: "<<error<<endl;
        }
    }

    // 收到远程返回的消息后, 此事件方法将被调用。
    void on_message_arrival(const boost::system::error_code& error, size_t size)
    {
        if ( error ) {
            cout<<"error: receive message failed, "<<error<<endl;
            return ;
        }

        // 参数size表示收到的字节数,收到的消息位于m_buffer_1
        m_buffer_1[size] = ‘\0‘;
        cout<<m_buffer_1<<endl;

        // 收消息成功,根据不同的状态分别处理
        if ( m_status == string("connected")) {

            // 连接后,收到服务器欢迎消息,发送用户登录命令
            m_status = string("username_sent");
            cout<<"begin send user name"<<endl;
            m_sock.async_write_some(boost::asio::buffer(CMD_USER, strlen(CMD_USER)),
                                    boost::bind(&async_socket_handler::on_message_sent,
                                    this,
                                    boost::asio::placeholders::error,
                                    boost::asio::placeholders::bytes_transferred));
        } else if (m_status == string("username_sent")) {

            // 收到服务器用户名确认消息,接着发送口令命令
            m_status = "password_sent";
            cout<<"begin send password"<<endl;
            m_sock.async_write_some(boost::asio::buffer(CMD_PASS, strlen(CMD_PASS)),
                                    boost::bind(&async_socket_handler::on_message_sent,
                                    this,
                                    boost::asio::placeholders::error,
                                    boost::asio::placeholders::bytes_transferred));
        } else if (m_status == string("password_sent")) {

            // 发送quit命令
            m_status = "quit_sent";
            cout<<"begin send quit"<<endl;
            m_sock.async_write_some(boost::asio::buffer(CMD_QUIT, strlen(CMD_QUIT)),
                                    boost::bind(&async_socket_handler::on_message_sent,
                                    this,
                                    boost::asio::placeholders::error,
                                    boost::asio::placeholders::bytes_transferred));
        }
        return ;
    }
};


int main()
{
    boost::asio::io_service     ioservice;
    tcp::socket    socket(ioservice);
    tcp::endpoint  endpoint;
    boost::system::error_code errcode;
    tcp::resolver resolver(ioservice);
    tcp::resolver::iterator iter_endpoint, iter_null;
    tcp::resolver::query query(MAIL_SERVER, "pop3");
    async_socket_handler handler(socket);  // 处理socket异步事件回调

    // 域名解析
    iter_endpoint = resolver.resolve(query, errcode);
    endpoint = iter_endpoint->endpoint();

    try {
        // 首先执行异步连接,此后的操作在async_socket_handler中
        // 根据不同的命令状态一次完成。
        socket.async_connect(endpoint,
                             boost::bind(&async_socket_handler::on_connected,
                                         &handler,
                                         boost::asio::placeholders::error));
        ioservice.run();  // 启动异步io过程
        cout<<"io service running finished"<<endl;
        socket.close();  // 通讯过程完成后,关闭socket
    } catch (const boost::system::system_error& e) {
        cout<<"connect error: "<<e.what()<<endl;
    }
    return 0;
} // end of main


boost_asio学习笔记[2] - 客户端异步通讯

标签:

原文地址:http://my.oschina.net/luckysym/blog/469317

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!