博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
boost.asio系列——socket编程
阅读量:7092 次
发布时间:2019-06-28

本文共 3045 字,大约阅读时间需要 10 分钟。

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。

转载地址:http://mnnql.baihongyu.com/

你可能感兴趣的文章
查看硬件信息几种方法
查看>>
MikroTik RouterOS-常用配置命令
查看>>
LVS DR + Keepalived 负载均衡配置详解(测试篇)
查看>>
Linux命令详解
查看>>
Quartz Job Scheduling Framework Reading Note(四)
查看>>
DN启动“假死?”
查看>>
结合Resumable.js实现在Server端PHP支持的大文件上传、断点续传功能
查看>>
PCL点云特征描述与提取(1)
查看>>
【HIMI转载推荐之三】基于Cocos2dx引擎UI扩展引擎包[cocos2d-x-3c] 转载xiaominghimi
查看>>
Oracle Weblogic 之---字符安装全记录
查看>>
JVM初探 -JVM内存模型
查看>>
Prisma推出2B业务,你的App也能用上最红的爆款滤镜了!
查看>>
.NET Framework 3.5 SP1安装时下载文件问题及精简方法
查看>>
[Offer收割]编程练习赛3 - 题目3 : 智力竞赛
查看>>
暴搜 - Codeforces Round #327 (Div. 2) E. Three States
查看>>
W32TM注册time.windows.com作为权威时间同步源
查看>>
FreeBsdb FAMP Lamp环境
查看>>
vsphere5.1.vSphere_5.0简介. 第二第三部分视频共享
查看>>
Centos 5 配置nagios监控系统
查看>>
需求管理之如何撰写优秀的需求
查看>>