服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - boost.asio框架系列之socket编程

boost.asio框架系列之socket编程

2022-12-29 14:06天方 C/C++

这篇文章介绍了boost.asio框架系列之socket编程,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

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

客户端

客户端的代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#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;
}

主要流程如下:

  • 通过tcp::socket类定义一个tcp client对象socket

  • 通过connect函数连接服务器,打开socket连接。

  • 通过read_some函数来读数据

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

服务器

服务器代码如下:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
#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;
}

主要流程如下:

  • 通过tcp::acceptor类创建一个tcp server对象,并绑定端口(也可以不在构造器中自动绑定,而通过bind函数手动绑定)

  • 通过accept函数获取远端连接

  • 通过远端连接的write_some函数将数据发往客户端

异步服务器

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#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来实现的自动释放。

到此这篇关于boost.asio框架系列之socket编程的文章就介绍到这了。希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://www.cnblogs.com/TianFang/archive/2013/02/02/2890529.html

延伸 · 阅读

精彩推荐
  • C/C++C++模板全方位深入解读

    C++模板全方位深入解读

    人们需要编写多个形式和功能都相似的函数,因此有了函数模板来减少重复劳动;人们也需要编写多个形式和功能都相似的类,于是 C++ 引人了类模板的概...

    林慢慢脑瓜子嗡嗡的4832022-12-16
  • C/C++C语言文件操作总结

    C语言文件操作总结

    本篇文章给大家通过代码示例讲述了C语言文件操作的相关知识点,对此有兴趣的朋友可以参考学习下。...

    Andrew_qian9012021-06-21
  • C/C++C语言全面梳理文件操作方法

    C语言全面梳理文件操作方法

    这篇文章主要为大家详细介绍了C语言的文件操作,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带...

    Iceevov3972022-11-29
  • C/C++详解c++ 继承

    详解c++ 继承

    这篇文章主要介绍了c++ 继承的相关资料,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...

    菜鸟教程4802021-09-16
  • C/C++Qt CEF融合技QCefView使用教程(推荐)

    Qt CEF融合技QCefView使用教程(推荐)

    QCefView是一个与Chromium Embedded Framework集成的Qt第三方开源库,LGPL许可,可以在项目中免费使用,功能类似CEF、QWebEngineView,提供C++和web交互的能力,本文给大...

    令狐掌门6062022-07-13
  • C/C++c++ 解析yaml文件的步骤

    c++ 解析yaml文件的步骤

    这篇文章主要介绍了c++ 解析yaml文件的步骤,帮助大家更好的理解和使用c++,感兴趣的朋友可以了解下...

    li-peng11132021-10-14
  • C/C++C++字符串输入缓冲区机制详解

    C++字符串输入缓冲区机制详解

    缓冲区是用来存放流中的数据,本文详细的介绍了C++字符串输入缓冲区机制,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助...

    srymakerTT3502022-02-16
  • C/C++OpenGL通过中点法绘制直线和圆

    OpenGL通过中点法绘制直线和圆

    这篇文章主要为大家详细介绍了OpenGL通过中点法绘制直线和圆,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    陳紋欽5842021-08-18