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

使用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
时间: 2024-10-06 17:46:57

boost_asio学习笔记[2] - 客户端异步通讯的相关文章

Mina框架的学习笔记——Android客户端的实现

Apache MINA(Multipurpose Infrastructure for Network Applications) 是 Apache 组织一个较新的项目,它为开发高性能和高可用性的网络应用程序提供了非常便利的框架.当前发行的 MINA 版本支持基于 Java NIO 技术的 TCP/UDP 应用程序开发.串口通讯程序(只在最新的预览版中提供),MINA 所支持的功能也在进一步的扩展中.目前正在使用 MINA 的软件包括有:Apache Directory Project.Asyn

SilverLight学习笔记--使用WebClient实现通讯(一)(上传和下载字符串数据)

一.什么是WebClient类   1.基本知识    WebClient类是Mircsoft在.NET框架下提供的向 URI 标识的资源发送数据和从 URI 标识的资源接收数据的公共方法.通过这个类,大家可以在脱离浏览器的基础上模拟浏览器对互联网上的资源的访问和发送信息.它使人们使用起来更加简单方便,然而它也有先天不足的地方.那就是缺少对cookies/session的支持.    WebClient类为Silverlight插件提供了一整套的HTTP客户端功能,可以下载应用程序数据,比如XA

WCF学习笔记(2)-WCF的通讯过程

一.WCF中的ABC 场景:公司让你送一份合同文件,送文件的过程你可以选择的交通方式有打的,地铁或公交. 到了对方公司后,你要找到某负责人,并且要一份收到合同文件的回执和相应文件 要完成这项工作任务主要以下几个步骤 1.知道对方公司的地址 即WCF中的A,通过Address我们可以找到我们要调用的WCF服务 2.选择交通方式 即WCF中的B,通过Binding来实现Client和Service通讯的所有底层细节. 传输采用什么编码,传输使用什么协议,等等 3.到了对方公司我们能做哪些事 即WCF

Android学习笔记十:异步处理

转载请注明原文地址:http://www.cnblogs.com/ygj0930/p/7520700.html 一:基础概念 UI线程:当Android程序第一次启动时,Android会同时启动一条主线程(Main Thread),主线程主要负责处理与UI相关的事件,如用户的按键事件.屏幕绘图事件,并把相关的事件分发到对应的组件进行处理.主线程通常又被称为UI线程,Android只允许UI线程修改Activity里的UI组件. 子线程:在程序的activity中创建.启动的线程为子线程,子线程中

HTML5学习笔记之客户端存储数据方法:localStorage(),sessionStorage()

HTML5提供了两种在客户端存储数据的新方法: localStorage():没有时间限制的数据存储 sessionStorage():针对一个session的数据存储 下面的一个例子用localStroage()方法对用户访问页面的次数进行计数 <script type="text/javascript"> if(localStorage.pagecount) { localStorage.pagecount=Number(localStorage.pagecount)+

SVN学习笔记二——客户端使用

SVN部署完成并成功配置完成后,就是使用的事情了,对于SVN,使用最多的往往是开发人员而不是运维人员,所以可能一些开发人员在这方面都比运维人员更熟悉,在我的工作经历中就曾有一个开发自行搭建SVN并且给开发和运维做培训的,强! 好了,上面主要是说其实对于SVN使用反而是开发比较在行,所以这里就简单的记录一下SVN客户端的使用吧. Windows客户端的使用(TortoiseSVN) 1.安装TortoiseSVN,注意软件区分32位和64位,下载的时候请下载对应版本,然后安装只需下一步到完成即可.

STM32学习笔记——SPI串行通讯(向原子哥学习)

一.SPI  简介 SPI是 Serial Peripheral interface 的缩写,就是串行外围设备接口.SPI 接口主要应用在  EEPROM, FLASH,实时时钟,AD 转换器,还有数字信号处理器和数字信号解码器之间.SPI,是一种高速的,全双工,同步的通信总线,并且在芯片的管脚上只占用四根线,节约了芯片的管脚,同时为 PCB 的布局上节省空间,提供方便,正是出于这种简单易用的特性,现在越来越多的芯片集成了这种通信协议,STM32 有 SPI 接口.下面是 SPI 的内部简明图:

Python学习笔记 - day14 - Celery异步任务

Celery概述 关于celery的定义,首先来看官方网站: Celery(芹菜) 是一个简单.灵活且可靠的,处理大量消息的分布式系统,并且提供维护这样一个系统的必需工具. 简单来看,是一个基于python开发的分布式异步消息任务队列,持使用任务队列的方式在分布的机器.进程.线程上执行任务调度.通过它可以轻松的实现任务的异步处理, 如果你的业务场景中需要用到异步任务,就可以考虑使用celery, 举几个实例场景中可用的例子: 你想对100台机器执行一条批量命令,可能会花很长时间 ,但你不想让你的

7.swoole学习笔记--tcp客户端

<?php //创建tcp客户端 $client=new swoole_client(SWOOLE_SOCK_TCP); //连接服务器 $client->connect('192.168.10.1',8080,5) or die("连接失败"); //向服务器发送数据 $client->send("hello world123") or die("数据发送失败"); //从服务器接收数据 $data=$client->r