Java教程

Boost ASIO 实现异步IO远控

本文主要是介绍Boost ASIO 实现异步IO远控,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

Boost 利用ASIO实现一个跨平台的远控程序,该远控支持保存套接字,当有套接字连入时,自动存储到map容器,需要时直接获取特定套接字实现通信。

客户端代码:

#ifdef _MSC_VER
#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#define _WIN32_WINNT 0x0601
#endif

#include <iostream>
#include <boost\array.hpp>
#include <boost\bind.hpp>
#include <boost\noncopyable.hpp>
#include <boost\asio.hpp>

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

int main(int argc, char* argv[])
{
    try
    {
        io_service service;
        tcp::socket socket(service);
        boost::system::error_code error;
        tcp::endpoint endpoint(address_v4::from_string("127.0.0.1"), 10000);
        socket.connect(endpoint, error);

        while (1)
        {
            // 客户端接收数据包
            boost::array<char, 4096> buffer = { 0 };
            socket.read_some(boost::asio::buffer(buffer), error);
            std::cout << "接收服务端数据: " << buffer.data() << std::endl;

            // 客户端发送数据
            socket.write_some(boost::asio::buffer("cliend message"));
        }
    }
    catch (exception& e){
        string s = e.what();
    }

    std::system("pause");
    return 0;
}

服务端代码1:

#include <string>
#include <vector>
#include <iostream>

using namespace std;

// 存储当前客户端的ID号
std::vector<int> tcp_client_id;

class EventHandler : public TcpServer::IEventHandler
{
public:
    // 客户端连接时触发
    virtual void ClientConnected(int clientId)
    {
        // 将登录客户端加入到容器中
        // cout << "客户端ID: " << clientId << endl;
        tcp_client_id.push_back(clientId);
    }

    // 客户端退出时触发
    virtual void ClientDisconnect(int clientId)
    {
        // 将登出的客户端从容器中移除
        // cout << "客户端ID: " << clientId << endl;
        vector<int>::iterator item = find(tcp_client_id.begin(), tcp_client_id.end(), clientId);
        if (item != tcp_client_id.cend())
            tcp_client_id.erase(item);
    }

    // 客户端获取数据
    virtual void ReceiveData(int clientId, const BYTE* data, size_t length)
    {
        // cout << "客户端ID: " << clientId << endl;
        std::cout <<"返回数据: " <<  data << " 返回长度: " << length << std::endl;
    }
};

// 同步发送数据到指定的线程中
void send_message(TcpServer &tcpServer, int clientId, std::string message)
{
    BYTE* buf = new BYTE(message.length() + 1);
    // std::cout << "长度: " << message.length() << std::endl;
    int i;
    for (int i = 0; i<message.length(); i++)
    {
        buf[i] = message.at(i);
    }
    std::cout << "发送数据: " << buf << std::endl;
    tcpServer.Send(clientId, buf, message.length());
}

int main(int argc, char* argv[])
{
    std::map<int, std::string> ptr;

    TcpServer tcpServer(10, 10000);
    EventHandler eventHandler;
    tcpServer.AddEventHandler(&eventHandler);

    string flag;
    while (1)
    {
        _sleep(1000);
        std::cout << "输入命令: ";
        cin >> flag;
        // 发送一条测试消息
        if (flag == "send")
        {
            int the_id;
            std::cout << "输入发送序号: ";
            std::cin >> the_id;
            send_message(tcpServer, the_id, "hello lyshark");
        }

        // 输出当前在线的IP地址列表
        else if (flag == "list")
        {
            std::cout << "--------------------------------------------" << std::endl;
            for (int x = 0; x < tcp_client_id.size(); x++)
            {
                std::cout << "客户端序号: " << tcp_client_id[x]
                << "  客户端IP: " << tcpServer.GetRemoteAddress(tcp_client_id[x]) 
                << std::endl;
            }
            std::cout << "--------------------------------------------" << std::endl;
        }
    }
    return 0;
}

客户端2: 增加异步连接超时机制。

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <string>
#include <boost/asio.hpp> 
#include <boost/bind.hpp>  
#include <boost/array.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>  
#include <boost/noncopyable.hpp>

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

// 异步连接地址与端口
class AsyncConnect
{
public:
    AsyncConnect(boost::asio::io_service& ios, tcp::socket &s)
        :io_service_(ios), timer_(ios), socket_(s) {}

    // 异步连接
    bool aysnc_connect(const tcp::endpoint &ep, int million_seconds)
    {
        bool connect_success = false;

        // 异步连接,当连接成功后将触发 connect_handle 函数
        socket_.async_connect(ep, boost::bind(&AsyncConnect::connect_handle, this, _1, boost::ref(connect_success)));

        // 设置一个定时器  million_seconds 
        timer_.expires_from_now(boost::posix_time::milliseconds(million_seconds));
        bool timeout = false;

        // 异步等待 如果超时则执行 timer_handle
        timer_.async_wait(boost::bind(&AsyncConnect::timer_handle, this, _1, boost::ref(timeout)));
        do
        {
            // 等待异步操作完成
            io_service_.run_one();
            // 判断如果timeout没超时,或者是连接建立了,则不再等待
        } while (!timeout && !connect_success);
        timer_.cancel();
        return connect_success;
    }

private:
    // 如果连接成功了,则 connect_success = true
    void connect_handle(boost::system::error_code ec, bool &connect_success)
    {
        if (!ec)
        {
            connect_success = true;
        }
    }

    // 定时器超时timeout = true
    void timer_handle(boost::system::error_code ec, bool &timeout)
    {
        if (!ec)
        {
            socket_.close();
            timeout = true;
        }
    }
    boost::asio::io_service &io_service_;
    boost::asio::deadline_timer timer_;
    tcp::socket &socket_;
};

int main(int argc, char * argv[])
{
    try
    {
        boost::asio::io_service io;
        tcp::socket socket(io);
        AsyncConnect hander(io, socket);
        boost::system::error_code error;
        tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 10000);

        // 循环验证是否在线
        while (1)
        {
            // 验证是否连接成功,并定义超时时间为3秒
            if (hander.aysnc_connect(ep, 5000))
            {
                io.run();
                std::cout << "已连接到服务端." << std::endl;

                // 循环接收命令
                while (1)
                {
                    // 客户端接收数据包
                    boost::array<char, 4096> buffer = { 0 };
                    socket.read_some(boost::asio::buffer(buffer), error);
                    // std::cout << "接收服务端数据: " << buffer.data() << std::endl;


                    // 判断收到的命令是否为GetCPU
                    if (strncmp(buffer.data(), "GetCPU", strlen("GetCPU")) == 0)
                    {
                        std::cout << "获取CPU参数并返回给服务端." << std::endl;
                        socket.write_some(boost::asio::buffer("CPU: 15 %"));
                    }
                    
                    // 判断收到的命令是否为终止程序
                    if (strncmp(buffer.data(), "Exit", strlen("Exit")) == 0)
                    {
                        std::cout << "终止客户端." << std::endl;
                        return 0;
                    }
                }
            }
            else
            {
                std::cout << "连接失败,正在重新连接." << std::endl;
            }
        }
    }
    catch (...)
    {
        return false;
    }

    std::system("pause");
    return 0;
}

客户端3:增加心跳检测:

#define BOOST_BIND_GLOBAL_PLACEHOLDERS
#include <iostream>
#include <string>
#include <boost/asio.hpp> 
#include <boost/bind.hpp>  
#include <boost/array.hpp>
#include <boost/date_time/posix_time/posix_time_types.hpp>  
#include <boost/noncopyable.hpp>

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

// 异步连接地址与端口
class AsyncConnect
{
public:
    AsyncConnect(boost::asio::io_service& ios, tcp::socket &s)
        :io_service_(ios), timer_(ios), socket_(s) {}

    // 异步连接
    bool aysnc_connect(const tcp::endpoint &ep, int million_seconds)
    {
        bool connect_success = false;

        // 异步连接,当连接成功后将触发 connect_handle 函数
        socket_.async_connect(ep, boost::bind(&AsyncConnect::connect_handle, this, _1, boost::ref(connect_success)));

        // 设置一个定时器  million_seconds 
        timer_.expires_from_now(boost::posix_time::milliseconds(million_seconds));
        bool timeout = false;

        // 异步等待 如果超时则执行 timer_handle
        timer_.async_wait(boost::bind(&AsyncConnect::timer_handle, this, _1, boost::ref(timeout)));
        do
        {
            // 等待异步操作完成
            io_service_.run_one();
            // 判断如果timeout没超时,或者是连接建立了,则不再等待
        } while (!timeout && !connect_success);
        timer_.cancel();
        return connect_success;
    }

    // 验证服务器端口是否开放
    bool port_is_open(std::string address, int port, int timeout)
    {
        try
        {
            boost::asio::io_service io;
            tcp::socket socket(io);
            AsyncConnect hander(io, socket);
            tcp::endpoint ep(boost::asio::ip::address::from_string(address), port);
            if (hander.aysnc_connect(ep, timeout))
            {
                io.run();
                io.reset();
                return true;
            }
            else
            {
                return false;
            }
        }
        catch (...)
        {
            return false;
        }
    }

private:
    // 如果连接成功了,则 connect_success = true
    void connect_handle(boost::system::error_code ec, bool &connect_success)
    {
        if (!ec)
        {
            connect_success = true;
        }
    }

    // 定时器超时timeout = true
    void timer_handle(boost::system::error_code ec, bool &timeout)
    {
        if (!ec)
        {
            socket_.close();
            timeout = true;
        }
    }
    boost::asio::io_service &io_service_;
    boost::asio::deadline_timer timer_;
    tcp::socket &socket_;
};

int main(int argc, char * argv[])
{
    try
    {
        boost::asio::io_service io;
        tcp::socket socket(io);
        AsyncConnect hander(io, socket);
        boost::system::error_code error;
        tcp::endpoint ep(boost::asio::ip::address::from_string("127.0.0.1"), 10000);

        // 循环验证是否在线
    while (1)
        {
            // 验证是否连接成功,并定义超时时间为5秒
            if (hander.aysnc_connect(ep, 5000))
            {
                io.run();
                std::cout << "已连接到服务端." << std::endl;

                // 循环接收命令
                while (1)
                {
                    // 验证地址端口是否开放,默认等待5秒
                    bool is_open = hander.port_is_open("127.0.0.1", 10000,5000);

                    // 客户端接收数据包
                    boost::array<char, 4096> buffer = { 0 };

                    // 如果在线则继续执行
                    if (is_open == true)
                    {
                        socket.read_some(boost::asio::buffer(buffer), error);

                        // 判断收到的命令是否为GetCPU
                        if (strncmp(buffer.data(), "GetCPU", strlen("GetCPU")) == 0)
                        {
                            std::cout << "获取CPU参数并返回给服务端." << std::endl;
                            socket.write_some(boost::asio::buffer("CPU: 15 %"));
                        }

                        // 判断收到的命令是否为GetMEM
                        if (strncmp(buffer.data(), "GetMEM", strlen("GetMEM")) == 0)
                        {
                            std::cout << "获取MEM参数并返回给服务端." << std::endl;
                            socket.write_some(boost::asio::buffer("MEM: 78 %"));
                        }

                        // 判断收到的命令是否为终止程序
                        if (strncmp(buffer.data(), "Exit", strlen("Exit")) == 0)
                        {
                            std::cout << "终止客户端." << std::endl;
                            return 0;
                        }
                    }
                    else
                    {
                    }
                }
            }
            else
            {
                std::cout << "连接失败,正在重新连接." << std::endl;
            }
        }
    }
    catch (...)
    {
        return false;
    }

    std::system("pause");
    return 0;
}

这篇关于Boost ASIO 实现异步IO远控的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!