asio的主要用途还是用于socket编程,本文就以一个tcp的daytimer服务为例简单的演示一下如何实现同步和异步的tcp socket编程。

客户端

客户端的代码如下:

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

using boost::asio::ip::tcp;

int main(int argc, char* argv[])
    {
        try
        {
            boost::asio::io_service io_service;
            tcp::endpoint end_point(boost::asio::ip::address::from_string("127.0.0.1"), 3200);

tcp::socketsocket(io_service);
            socket.connect(end_point);

for (;;)
            {
                boost::array<char, 128> buf;
                boost::system::error_code error;

size_t len = socket.read_some(boost::asio::buffer(buf), error);

if (error == boost::asio::error::eof)
                    break; // Connection closed cleanly by peer.
                else if (error)
                    throw boost::system::system_error(error); // Some other error.

std::cout.write(buf.data(), len);
            }
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }

return 0;
    }

主要流程如下:

  1. 通过tcp::socket类定义一个tcp client对象socket
  2. 通过connect函数连接服务器,打开socket连接。
  3. 通过read_some函数来读数据

另外,还可以通过write_some来写数据,通过close来关闭socket连接(这里是通过释放socket对象隐式释放连接)。

服务器

服务器代码如下:

#include <ctime>
    #include <iostream>
    #include <string>
    #include <boost/asio.hpp>

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

int main()
    {
        try
        {
            asio::io_service io_service;
            tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3200));

for (;;)
            {
                tcp::socket socket(io_service);
                acceptor.accept(socket);

time_t now = time(0);
                std::string message = ctime(&now);

system::error_code ignored_error;
                socket.write_some(asio::buffer(message), ignored_error);
            }
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }

return 0;
    }

主要流程如下:

  1. 通过tcp::acceptor类创建一个tcp server对象,并绑定端口(也可以不在构造器中自动绑定,而通过bind函数手动绑定)
  2. 通过accept函数获取远端连接
  3. 通过远端连接的write_some函数将数据发往客户端

异步服务器

前面的服务器是同步版本,在大并发的场景下一般需要用到异步socket。服务器的异步版本如下:

#include <ctime>
    #include <iostream>
    #include <string>
    #include <memory>
    #include <functional>
    #include <boost/asio.hpp>

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

void process_client(shared_ptr<tcp::socket> client)
    {
        time_t now = time(0);
        shared_ptr<string> message(new string(ctime(&now)));

auto callback = [=](const boost::system::error_code& err ,size_t size)
        {
            if ((int)size == message->length())
                cout << "write completed" << endl;
        };

client->async_send(boost::asio::buffer(*message), callback);
    }

typedef function<void (const boost::system::error_code&)> accept_callback;
    void start_accept(tcp::acceptor& server)
    {
        shared_ptr<tcp::socket> client(new tcp::socket(server.get_io_service()));
        accept_callback callback = [&server, client](const boost::system::error_code& error)
            {
                if (!error)
                    process_client(client);

start_accept(server);
            };

server.async_accept(*client, callback);
    }

int main()
    {
        try
        {
            boost::asio::io_service io_service;
            tcp::acceptor acceptor(io_service, tcp::endpoint(tcp::v4(), 3200));
            start_accept(acceptor);
            io_service.run();
        }
        catch (std::exception& e)
        {
            std::cerr << e.what() << std::endl;
        }
        return 0;
    }

这个异步版本的逻辑倒不是很复杂,基本上和.net中传统的异步socket相似,不过需要注意的是,由于c++中内存需要自己管理,而asio框架也没有提供任何管理机制,因此需要注意async_accept、async_send等函数的参数生命周期,切记不能在里面传入栈变量的引用。如果是堆变量,需要确保释放,本例中我是通过share_ptr来实现的自动释放。

更多的示例请参看asio官方文档

FROM:http://www.cnblogs.com/TianFang/archive/2013/02/02/2890529.html

boost.asio系列——socket编程的更多相关文章

  1. Boost.Asio c++ 网络编程翻译(20)

    异步服务端 这个图表是相当复杂的:从Boost.Asio出来你能够看到4个箭头指向on_accept.on_read,on_write和on_check_ping. 着也就意味着你永远不知道哪个异步调 ...

  2. Boost.Asio c++ 网络编程翻译(14)

    保持活动 假如,你须要做以下的操作: io_service service; ip::tcp::socket sock(service); char buff[512]; ... read(sock, ...

  3. Boost.Asio c++ 网络编程翻译(26)

    Boost.Asio-其他特性 这章我们讲了解一些Boost.Asio不那么为人所知的特性.标准的stream和streambuf对象有时候会更难用一些,但正如你所见.它们也有它们的益处.最后,你会看 ...

  4. Boost.Asio c++ 网络编程翻译(21)

    同步VS异步 Boost.Asio的作者做了一个非常惊艳的工作:它能够让你在同步和异步中自由选择,从而更好的适应你的应用. 在之前的章节中,我们学习了每种类型应用的框架,比方同步client,同步服务 ...

  5. Boost.Asio c++ 网络编程翻译(11)

    *_at方法 这些方法在一个流上面做随机存取操作.你来指定read和write操作从什么地方開始(offset): async_read_at(stream, offset, buffer [, co ...

  6. boost.asio系列——io_service

    IO模型 io_service对象是asio框架中的调度器,所有异步io事件都是通过它来分发处理的(io对象的构造函数中都需要传入一个io_service对象). asio::io_service i ...

  7. boost boost::asio::read socket.read_some 区别

    boost boost::asio::read 尝试读一定数量的字节,直到读到为止,或者出错 socket.read_some 读一下socket,读到多少算多少 带async的类似

  8. Boost.Asio c++ 网络编程翻译(16)

    TCP异步服务端 核心功能和同步服务端的功能类似,例如以下: class talk_to_client : public boost::enable_shared_from_this<talk_ ...

  9. Boost.Asio c++ 网络编程翻译(10)

    read/write方法 这些方法对一个流进行读写操作(能够是套接字,或者其它表现的像流的类): async_read(stream, buffer [, completion],handler):这 ...

随机推荐

  1. CodeForces 543A - Writing Code DP 完全背包

    有n个程序,这n个程序运作产生m行代码,但是每个程序产生的BUG总和不能超过b, 给出每个程序产生的代码,每行会产生ai个BUG,问在总BUG不超过b的情况下, 我们有几种选择方法思路:看懂了题意之后 ...

  2. js中innerHTML与innerText的用法与区别

    用法: <div id="test">    <span style="color:red">test1</span> te ...

  3. 基于visual Studio2013解决C语言竞赛题之0604二维数组置换

     题目

  4. java中可以出现的中文乱码的集中解决

    从学习javaweb开始就会经常遇到中文乱码,今天就做以下记录: 1. 要避免项目中遇到乱码,首先就是在搭建项目的设置工作空间的字符编码,若是多人开发,就更应该做到统一,在eclipse中选择widn ...

  5. Ext.net中常用的三种交互方式

    http://www.ext.net.cn/forum.php?mod=viewthread&tid=10433

  6. Qt 智能指针学习(7种QT智能指针和4种std智能指针)

    从内存泄露开始? 很简单的入门程序,应该比较熟悉吧 ^_^ #include <QApplication> #include <QLabel> int main(int arg ...

  7. 通过jQuery的attr修改onclick

    var js = "alert('B:' + this.id); return false;"; // creates a function from the "js&q ...

  8. poj 1155 TELE (树形背包dp)

    本文出自   http://blog.csdn.net/shuangde800 题目链接: poj-1155 题意 某收费有线电视网计划转播一场重要的足球比赛.他们的转播网和用户终端构成一棵树状结构, ...

  9. C#中ref参数及out参数对比

    ref 关键字和out关键字均会导致参数通过引用来传递(相同点1).这是两者的共同点. 通过引用传递参数,会使方法中对参数所做的任何修改都将反映在该变量中. 两者还有一个共同点,那就是:若要使用 re ...

  10. UITableViewHeaderFooterView的使用+自己主动布局

    UITableViewHeaderFooterView的使用+自己主动布局 使用UITableView的header或footer复用时,假设採用自己主动布局,你会发现有约束冲突,以下这样写能够消除约 ...