boost::asio中的C/S同步实例源码

近来狂热地研究boost的开发技术,现将读书笔记整理如下:

需要说明的是, 本博该专题下面关于boost的源码是采用boost1.55版本, 运行在Ubuntu 14.04 64bit下面, 使用apt包安装(非源码编译安装), 后续不再做说明.

同步socket类型的服务器源码实现:

//g++ -g sync_tcp_server.cpp -o sync_tcp_server -lboost_system
//

#include <iostream>
#include <boost/asio.hpp>
#include <boost/system/error_code.hpp>

using namespace std;
using namespace boost::asio;

int main(){
    try{
        cout << "sync tcp server start ......" << endl;
        io_service ios;

        //server listen at 127.0.0.1:6688
        ip::tcp::acceptor acceptor(ios, ip::tcp::endpoint(ip::tcp::v4(), 6688));
        cout << acceptor.local_endpoint().address() << endl;

        while(true){
            ip::tcp::socket sock(ios);
            acceptor.accept(sock);

            cout << "client: ";
            cout << sock.remote_endpoint().address() << endl;

            sock.write_some(buffer("hello asio"));
        }
    }
    catch(std::exception& e){
        cout << e.what() << endl;
    }
}

同步socket类型的客户端源码实现:

//g++ -g sync_tcp_client.cpp -o sync_tcp_client -lboost_system -lboost_date_time
//

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

using namespace boost::asio;

void client(io_service &ios){
    try {
        std::cout << "sync client starting ......" << std::endl;

        ip::tcp::socket sock(ios);
        ip::tcp::endpoint ep(ip::address::from_string("127.0.0.1"), 6688);
        sock.connect(ep);

        std::vector<char> str(100, 0);
        sock.read_some(buffer(str));
        std::cout << "receive from: " << sock.remote_endpoint().address() << std::endl;
        std::cout << &str[0] << std::endl;
    } catch (std::exception &e) {
        std::cout << e.what() << std::endl;
    }
}

class a_timer
{
    private:
        int count, count_max;
        boost::function<void()> f;
        boost::asio::deadline_timer t;

    public:
        template<typename F>
        a_timer(io_service &ios, int x, F func): f(func), count_max(x), count(0),
            t(ios, boost::posix_time::millisec(500)) {
                t.async_wait(boost::bind(&a_timer::call_func, this, boost::asio::placeholders::error));
            }

        void call_func(const boost::system::error_code&)
        {
            if (count >= count_max) {
                return;
            }
            ++count;
            f();
            t.expires_at(t.expires_at() + boost::posix_time::millisec(500));
            t.async_wait(boost::bind(&a_timer::call_func, this, boost::asio::placeholders::error));
        }

};

int main()
{
    io_service ios;
    a_timer at(ios, 5, boost::bind(client, boost::ref(ios)));

    ios.run();

    return 0;
}

运行细节:



注意所有的源码均在Ubuntu 14.04 64bit上运行测试, 比参考文献[1]中更详细更具体.


参考文献:

[1].罗剑锋, Boost程序库完全开发指南---深入C++"准"标准库

st_asio_wrapper是一组类,功能是对boost.asio的包装(调试环境:boost-1.51.0),目的是简化boost.asio开发; 其特点是效率高、跨平台、完全异步,当然这是从boost.asio继承而来; 自动重连,数据透明传输,自动解决分包粘包问题(你可以像udp一样使用它); 注:只支持tcp协议; 教程:http://blog.csdn.net/yang79tao/article/details/7724514 1.1版更新内容: 增加了自定义数据模式的支持,可用于st_asio_wrapper server与其它客户端的通信、或者st_asio_wrapper client与其它服务端的通信;当然,两端都是st_asio_wrapper的话,就用透明传输即可(1.0版已经支持了)。 1.2版更新内容: 修复BUG:当stop_service之后,再start_service时,client_base内部某些成员变量可能没有得到复位; 服务端增加修改监听地址功能,当然仍然要在start_service之前调用set_server_addr函数。 1.3版更新内容: 增加自定义消息格式的发送,这个本来是在1.1版本实现的,结果我漏掉了,只实现了自定义消息格式的接收。 1.4版更新内容: 将打包与解包器从client_base分离出来,以简化这个日益复杂的基类; 可以在运行时修改打包解包器。 1.5版更新内容: 增加ipv6支持,默认是ipv4,服务端和客户端都通过设置一个ipv6的地址来开启这个功能; 增加了一些服务端helper函数,小改了一下客户端set_server_addr函数签名(调换了两个参数的位置以保持和服务端一样)。 1.6版更新内容: 增加了接收消息缓存(改动较大,on_msg的语义有所变化,请看开发教程第三篇)。 1.7版更新内容: 修复vc2010下编译错误; 修复默认解包器BUG(同时修改解包器接口); 修复log输出BUG; 更好的包装了服务端类库,现在服务端可以像客户端一样简单的使用了(完全不用继承或者重写虚函数,申请一个对象即可); 结构大调整,类名大调整,请参看开发教程第一篇。 1.8版更新内容: 增加健壮性和稳定性; 退出服务更新优雅。 1.9版更新内容: 提高代码通用性; 可以指定服务端同时投递多少个async_accept; 修复BUG,此BUG可能造成数据发送不完全。 2.0版更新内容: 服务端增加对象池功能; 优化美化代码; 更规范化接口签名。 2.1版更新内容: 修复BUG,此BUG会造成st_client在stop_service之后,仍然可能尝试重新连接服务器; 在消息发送的时候,增加了一个参数can_overflow,用于确定是否在缓存满的时候返回失败,这在某些不能阻塞等待直到缓存可用的场合非常有用,比如on_msg; 当消息接收缓存满的时候,st_socket现在可以保证消息不丢失,之前的行为是调用on_recv_buffer_oveflow之后,丢弃消息; 更规范化接口签名; 更多更新请看st_asio_wrapper_socket.h,所有更新都会罗列在这个头文件的开头处,另外st_asio_wrapper_server.h的开头部分注释也很重要,有工作原理相关的说明。 2.2版更新内容: 增加了一个demo——文件传输服务端及客户端,它几乎可以当成软件来使用,多线程且支持分块传送; 增加了timer功能,考虑到st_server已经用上了timer,加之做文件传输服务器的时候,也用到了timer,所以干脆把timer抽象出来,其设计原理及使用跟MFC的timer差不多。timer已经被st_socket和st_server继承。用的时候,调用set_timer开始timer,重写on_timer虚函数等待被调用即可; 进一步优化消息接收缓存,通过宏,让优化发生于编译阶段,参看FORCE_TO_USE_MSG_RECV_BUFFER宏以了解更多。demo里面有使用案例(asio_server,asio_client,file_server,file_client,performance/asio_client); 增加了所有的宏都可以在外面修改的功能,在include类库头文件之前,可以定义你想要的宏,st_asio_wrapper不会修改它们,除非它们没有被定义,此时使用默认值,这也是st_asio_wrapper之前设计不好的地方,具体请参看使用教程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值