• 代理模式DDDDD+++++++boost io


    1. #include
    2. using namespace std;
    3. class Subject
    4. {
    5. public:
    6. virtual void request() = 0;
    7. virtual ~Subject() {}
    8. };
    9. class RealSubject : public Subject
    10. {
    11. public:
    12. void request() {
    13. cout << "RealSubject.request()" << endl;
    14. }
    15. };
    16. class Proxy : public Subject
    17. {
    18. private:
    19. Subject* realSubject;
    20. public:
    21. Proxy()
    22. {
    23. realSubject = new RealSubject();
    24. }
    25. ~Proxy()
    26. {
    27. delete realSubject;
    28. }
    29. // Forward calls to the RealSubject:
    30. void request() {
    31. realSubject->request();
    32. }
    33. };
    34. int main() {
    35. Proxy p;
    36. p.request();
    37. }

    C++网络代理实现

    以下是一个简化的C++网络代理服务器的核心代码示例,它展示了如何使用Boost.Asio库来实现一个简单的TCP代理。

     
    
     
    

    #include

    #include

    #include

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

    class proxy_server {

    public:

    proxy_server(boost::asio::io_service& io_service, short port)

    : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),

    socket_(io_service) {

    start_accept();

    }

    private:

    void start_accept() {

    acceptor_.async_accept(socket_, std::bind(&proxy_server::handle_accept, this, std::placeholders::_1));

    }

    void handle_accept(const boost::system::error_code& error) {

    if (!error) {

    std::thread t(std::bind(&proxy_server::proxy_client, this, std::ref(socket_)));

    t.detach();

    }

    start_accept();

    }

    void proxy_client(tcp::socket& client_socket) {

    // 实现代理逻辑,例如连接目标服务器,转发数据等

    }

    tcp::acceptor acceptor_;

    tcp::socket socket_;

    };

    int main() {

    try {

    boost::asio::io_service io_service;

    proxy_server server(io_service, 8080);

    io_service.run();

    } catch (std::exception& e) {

    std::cerr << e.what() << std::endl;

    }

    return 0;

    }

    这个简单的代码示例展示了如何使用Boost.Asio库来创建一个简单的TCP代理服务器。它接受客户端的连接请求,然后在新的线程中处理该连接。代理逻辑需要进一步实现,包括连接到目标服务器,以及双向数据的转发。这个示例只是展示了如何开始这样的工作,并没有完整实现代理的全部功能。

    ########################################################################################################################################################################################################################################

    C++基于Boost.Asio实现端口映射器的过程详解

     更新时间:2023年11月27日 09:52:15   作者:微软技术分享  

    Boost.Asio 是一个功能强大的 C++ 库,用于异步编程和网络编程,它提供了跨平台的异步 I/O 操作,在这篇文章中,我们将深入分析一个使用 Boost.Asio 实现的简单端口映射服务器,文中有详细的代码讲解,需要的朋友可以参考下

    目录

    前言

    Boost.Asio 是一个功能强大的 C++ 库,用于异步编程和网络编程,它提供了跨平台的异步 I/O 操作。在这篇文章中,我们将深入分析一个使用 Boost.Asio 实现的简单端口映射服务器,该服务器能够将本地端口的数据包转发到指定的远程服务器上。

    端口映射通常用于将一个网络端口上的流量转发到另一个网络端口。这对于实现网络中间人攻击、内网穿透等场景非常有用。我们将使用 Boost.Asio 提供的异步操作来实现这个简单而功能强大的端口映射服务器。

    1

    2

    3

    4

    5

    6

    7

    8

    #include

    #include

    #include

    #include

    #include

    #include

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

    首先,让我们简要概述代码的主要类:

    • socket_client 类:继承了 boost::enable_shared_from_this 和 tcp::socket,用于表示客户端的套接字。
    • socket_pipe 类:表示端口映射的管道,负责在两个客户端之间传递数据。
    • async_listener 类:用于异步监听指定端口的连接请求,通过回调函数处理连接。
    • port_map_server 类:管理多个监听器,支持添加端口映射规则,并处理连接请求。

    1.1 socket_client

    socket_client 类继承自 boost::enable_shared_from_this 和 tcp::socket。通过 create 静态方法创建一个 socket_client 实例,提供了共享指针的方式管理对象的生命周期。

    如下代码是一个使用 Boost.Asio 库创建的异步 TCP 客户端类。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    class socket_client

        : public boost::enable_shared_from_this

        , public tcp::socket

    {

    public:

        typedef boost::shared_ptr pointer;

        static pointer create(boost::asio::io_service& io_service)

        {

            return pointer(new socket_client(io_service));

        }

    public:

        socket_client(boost::asio::io_service& io_service)

            :tcp::socket(io_service)

        {

        }

    };

    以下是对该类的概括:

    • 类名socket_client
    • 继承关系
      • 继承自 boost::enable_shared_from_this,这允许在异步操作中安全地使用 shared_from_this,以避免悬挂指针的问题。
      • 继承自 tcp::socket,表示该类是一个 TCP 套接字。
    • 公共成员类型
      • pointerboost::shared_ptr 类型的别名,用于管理该类的实例。
    • 公共静态函数
      • create:工厂方法,用于创建 socket_client 的实例。通过此方法获取了一个智能指针指向新创建的实例。
    • 公共构造函数
      • socket_client(boost::asio::io_service& io_service):构造函数,接受一个 boost::asio::io_service 引用,用于初始化基类 tcp::socket

    该类的目的是提供一个异步 TCP 客户端的基本结构,使其能够与 Boost.Asio 库中的异步 I/O 操作协同工作。实际使用时,可以根据具体需求扩展该类,添加成员函数和操作,以实现特定的异步操作逻辑。

    1.2 socket_pipe

    socket_pipe 类用于处理两个客户端之间的数据传递。通过异步操作实现了从一个客户端读取数据,并将数据写入另一个客户端。出现错误时,会关闭两个客户端的连接。这里使用了递归的方式,实现了数据的循环传递。

    如下代码是一个使用是一个 socket_pipe 类的定义,用于在两个 socket_client 实例之间建立数据传输管道。

    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

    55

    56

    57

    58

    59

    60

    61

    62

    class socket_pipe

    {

    public:

        socket_pipe(socket_client::pointer read, socket_client::pointer write)

            :read_socket_(*read), write_socket_(*write)

        {

            read_ = read;

            write_ = write;

            begin_read();

        }

    private:

        void begin_read()

        {

            read_socket_.async_read_some(boost::asio::buffer(data_, max_length),

                boost::bind(&socket_pipe::end_read, this,

                    boost::asio::placeholders::error,

                    boost::asio::placeholders::bytes_transferred));

        }

        void end_read(const boost::system::error_code& error, size_t bytes_transferred)

        {

            if (error)

                handle_error(error);

            else

                begin_write(bytes_transferred);

        }

        void begin_write(int bytes_transferred)

        {

            boost::asio::async_write(write_socket_,

                boost::asio::buffer(data_, bytes_transferred),

                boost::bind(&socket_pipe::end_write, this,

                    boost::asio::placeholders::error));

        }

        void end_write(const boost::system::error_code& error)

        {

            if (error)

                handle_error(error);

            else

                begin_read();

        }

        void handle_error(const boost::system::error_code& error)

        {

            read_socket_.close();

            write_socket_.close();

            delete this;

        }

    private:

        socket_client& read_socket_;

        socket_client& write_socket_;

        socket_client::pointer read_;

        socket_client::pointer write_;

        enum { max_length = 1024 };

        char data_[max_length];

    };

    以下是对该类的概括:

    • 类名socket_pipe
    • 公共构造函数
      • socket_pipe(socket_client::pointer read, socket_client::pointer write):构造函数,接受两个 socket_client::pointer 实例,一个用于读取数据 (read_socket_),另一个用于写入数据 (write_socket_)。在构造函数中,调用了 begin_read 函数,启动了异步读取操作。
    • 私有成员函数
      • begin_read():启动异步读取操作,使用 read_socket_.async_read_some 异步读取数据。
      • end_read(const boost::system::error_code& error, size_t bytes_transferred):读取操作完成时的回调函数,处理可能的错误,如果没有错误则调用 begin_write 启动异步写入操作。
      • begin_write(int bytes_transferred):启动异步写入操作,使用 boost::asio::async_write 异步写入数据。
      • end_write(const boost::system::error_code& error):写入操作完成时的回调函数,处理可能的错误,如果没有错误则调用 begin_read 启动下一轮异步读取操作。
      • handle_error(const boost::system::error_code& error):处理错误的函数,关闭读取和写入套接字,并释放当前 socket_pipe 实例。
    • 私有成员变量
      • socket_client& read_socket_:引用传递的读取套接字。
      • socket_client& write_socket_:引用传递的写入套接字。
      • socket_client::pointer read_:指向读取套接字的智能指针。
      • socket_client::pointer write_:指向写入套接字的智能指针。
      • enum { max_length = 1024 };:定义了最大数据长度。
      • char data_[max_length];:存储数据的缓冲区。

    该类的主要目的是在两个 socket_client 之间实现数据的双向传输,通过异步操作实现了循环的读取和写入过程。在错误处理中,如果出现错误,会关闭套接字并释放当前的 socket_pipe 实例。

    1.3 async_listener

    async_listener 类负责异步监听指定端口,并通过回调函数处理连接。在连接建立时,会调用用户提供的回调函数进行处理。通过 begin_accept 方法开始异步监听。

    如下代码是一个使用 async_listener 类的定义,用于异步监听指定端口的连接。

    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

    class async_listener

    {

    public:

        typedef boost::function<void(socket_client::pointer client)> accept_handler;

        typedef boost::shared_ptr pointer;

    public:

        async_listener(short port, boost::asio::io_service& io_service)

            :io_service_(io_service),

            acceptor_(io_service, tcp::endpoint(tcp::v4(), port))

        {

            begin_accept();

        }

        void begin_accept()

        {

            socket_client::pointer client = socket_client::create(io_service_);

            acceptor_.async_accept(*client,

                boost::bind(&async_listener::end_accept, this, client,

                    boost::asio::placeholders::error));

        }

        void end_accept(socket_client::pointer client, const boost::system::error_code& error)

        {

            if (error)

                handle_error(error);

            begin_accept();

            if (!handle_accept.empty())

                handle_accept(client);

        }

        void handle_error(const boost::system::error_code& error)

        {

        }

    public:

        accept_handler handle_accept;

    private:

        tcp::acceptor acceptor_;

        boost::asio::io_service& io_service_;

    };

    以下是对该类的概括:

    • 类名async_listener
    • 公共成员类型
      • accept_handlerboost::function 类型的别名,用于定义连接建立时的回调函数。
      • pointerboost::shared_ptr 类型的别名,用于管理该类的实例。
    • 公共构造函数
      • async_listener(short port, boost::asio::io_service& io_service):构造函数,接受一个短整型端口号和一个 boost::asio::io_service 引用。在构造函数中,创建了一个 TCP 接受器 (acceptor_) 并调用 begin_accept 启动异步接受操作。
    • 公共函数
      • begin_accept():启动异步接受操作,创建一个新的 socket_client 实例,并调用 acceptor_.async_accept 异步等待连接的建立。
      • end_accept(socket_client::pointer client, const boost::system::error_code& error):异步接受操作完成时的回调函数,处理可能的错误,如果没有错误则调用 begin_accept 启动下一轮异步接受操作。如果定义了 handle_accept 回调函数,则调用它并传递新连接的 socket_client 实例。
    • 私有成员函数
      • handle_error(const boost::system::error_code& error):处理错误的函数,目前仅为空实现。
    • 公共成员变量
      • accept_handler handle_accept:用于存储用户定义的连接建立时的回调函数。
    • 私有成员变量
      • tcp::acceptor acceptor_:TCP 接受器,用于监听连接。
      • boost::asio::io_service& io_service_:引用传递的 io_service,用于执行异步操作。

    该类的主要目的是实现异步监听,一旦有连接建立,就通过回调函数通知用户,并通过 handle_error 处理可能的错误。在连接建立后,会继续监听新的连接。

    1.4 port_map_server

    port_map_server 类管理多个监听器,支持动态添加端口映射规则。在连接建立时,会调用 handle_accept 处理连接请求。通过 begin_connect 方法开始异步连接远程服务器。

    如下代码是一个 port_map_server 类的定义,它通过异步监听多个本地端口,并将连接映射到远程服务器的不同端口。

    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

    class port_map_server

    {

    public:

        port_map_server(boost::asio::io_service& io_service) :io_service_(io_service)

        {

        }

        void add_portmap(short port, tcp::endpoint& remote_endpoint)

        {

            async_listener::pointer listener(new async_listener(port, io_service_));

            listeners.push_back(listener);

            listener->handle_accept = boost::bind(&port_map_server::handle_accept

                , this, remote_endpoint, _1);

        }

        void handle_accept(tcp::endpoint remote_endpoint, socket_client::pointer client)

        {

            begin_connect(remote_endpoint, client);

        }

        void begin_connect(tcp::endpoint& remote_endpoint, socket_client::pointer socket_local)

        {

            socket_client::pointer socket_remote = socket_client::create(io_service_);

            socket_remote->async_connect(remote_endpoint,

                boost::bind(&port_map_server::end_connect, this,

                    boost::asio::placeholders::error, socket_local, socket_remote));

        }

        void end_connect(const boost::system::error_code& error, socket_client::pointer socket_local, socket_client::pointer socket_remote)

        {

            if (error)

            {

                handle_error(error);

            }

            else

            {

                new socket_pipe(socket_local, socket_remote);

                new socket_pipe(socket_remote, socket_local);

            }

        }

        void handle_error(const boost::system::error_code& error)

        {

        }

    private:

        boost::asio::io_service& io_service_;

        std::list listeners;

    };

    以下是对该类的概括:

    • 类名port_map_server
    • 公共构造函数
      • port_map_server(boost::asio::io_service& io_service):构造函数,接受一个 boost::asio::io_service 引用。
    • 公共函数
      • add_portmap(short port, tcp::endpoint& remote_endpoint):添加端口映射规则的函数。为指定端口创建一个新的 async_listener 实例,并将其添加到 listeners 列表中。同时,设置 handle_accept 回调函数,以便在新连接建立时调用 handle_accept 函数。
    • 私有成员函数
      • handle_accept(tcp::endpoint remote_endpoint, socket_client::pointer client):处理新连接建立时的回调函数。在此函数中,调用 begin_connect 启动异步连接到远程服务器的操作。
      • begin_connect(tcp::endpoint& remote_endpoint, socket_client::pointer socket_local):启动异步连接到远程服务器的操作,创建一个新的远程套接字。
      • end_connect(const boost::system::error_code& error, socket_client::pointer socket_local, socket_client::pointer socket_remote):处理异步连接操作完成时的回调函数。如果连接成功,创建两个 socket_pipe 实例,分别用于将数据从本地传输到远程和从远程传输回本地。
      • handle_error(const boost::system::error_code& error):处理错误的函数,目前仅为空实现。
    • 私有成员变量
      • boost::asio::io_service& io_service_:引用传递的 io_service,用于执行异步操作。
      • std::list listeners:存储多个 async_listener 实例的列表。

    该类的主要目的是通过创建多个 async_listener 实例,监听多个本地端口,并在新连接建立时将其映射到远程服务器的不同端口。在连接建立后,会启动异步连接到远程服务器的操作,并创建数据传输的管道。

    1.5 port_map_server

    这是程序的 main 函数,负责创建一个 boost::asio::io_service 实例,设置两个远程服务器的端点,然后创建一个 port_map_server 实例并添加两个端口映射规则。最后,通过调用 io_service.run() 开始事件循环。

    以下是对 main 函数的概括:

    • 函数功能
      • 创建一个 boost::asio::io_service 实例,用于管理异步操作的事件循环。
      • 定义两个远程服务器的端点 (ep1 和 ep2),分别是 192.168.1.100:80 和 192.168.1.200:80
      • 创建一个 port_map_server 实例,该实例使用上述 io_service
      • 通过 add_portmap 函数向 port_map_server 添加两个端口映射规则,将本地端口 5000 映射到远程服务器 192.168.1.100:80,将本地端口 6000 映射到远程服务器 192.168.1.200:80
      • 调用 io_service.run() 开始事件循环,等待异步操作的完成。
    • 异常处理
      • 使用了 try 和 catch 块,捕获任何可能抛出的异常,并在 catch 块中忽略异常。
    • 返回值
      • 返回整数 0 表示程序正常结束。

    这个 main 函数的作用是启动异步事件循环,使得 port_map_server 开始监听指定端口,接受连接,并将连接映射到远程服务器上。

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    13

    14

    15

    16

    17

    18

    19

    20

    21

    int main(int argc, char* argv[])

    {

        try

        {

            boost::asio::io_service io_service;

            tcp::endpoint ep1(boost::asio::ip::address_v4::from_string("192.168.1.100"), 80);

            tcp::endpoint ep2(boost::asio::ip::address_v4::from_string("192.168.1.200"), 80);

            port_map_server server(io_service);

            // 访问本机5000端口,将数据包转发到 8.141.58.64:80

            server.add_portmap(5000, ep1);

            // 访问本机6000端口,将数据包转发到 8.141.58.64:80

            server.add_portmap(6000, ep2);

            io_service.run();

        }

        catch (...) {}

        return 0;

    }

    以上就是C++基于Boost.Asio实现端口映射器的过程详解的详细内容,更多关于C++ Boost.Asio端口映射器的资料请关注脚本之家其它相关文章!

  • 相关阅读:
    Redis 做签到统计
    Java8实战-总结33
    生成指定位数的随机验证码
    RichView TRVStyle TextStyles
    前端跨页面通信的几种方式
    软件架构设计(十三) 构件与中间件技术
    解密Spring Cloud LoadBalancer:实现高效负载均衡的魔法密卷(二)
    统一身份认证登录详细介绍-identity4
    QT+OSG/osgEarth编译之二十一:FreeXL+Qt编译(一套代码、一套框架,跨平台编译,版本:FreeXL-1.0.6)
    LeetCode 1280. 学生们参加各科测试的次数
  • 原文地址:https://blog.csdn.net/lusic01/article/details/139831665