【问题标题】:C++ Boost Asio - How to detect disconnection and make a list of all active connectionsC++ Boost Asio - 如何检测断开连接并列出所有活动连接
【发布时间】:2020-09-16 10:10:51
【问题描述】:

我使用 Boost asio 作为 TCP 服务器解决方案。我希望我的服务器和客户端通过 TCP 二进制协议进行通信。

这是我的服务器代码:

服务器.cpp:

#include "Server.h"
#include "Session.h"

using namespace Vibranium;

void Server::do_accept()
{
    acceptor_.async_accept(socket_,
   [this](boost::system::error_code ec)
   {
       if (!ec)
       {
           std::cout << "Connected!" << std::endl;
           std::make_shared<Session>(std::move(socket_))->start();
       }

       do_accept();
   });
}

这里是 Session.cpp:

#include "Session.h"

void Vibranium::Session::start() {
    do_read();
}

void Vibranium::Session::do_read() {
    auto self(shared_from_this());
    socket_.async_read_some(boost::asio::buffer(data_, max_length),
    [this, self](boost::system::error_code ec, std::size_t length)
    {
        if (!ec)
        {
            std::cout.write(data_, length);
            std::cout << "\n";
            do_write(length);
        }
    });
}

void Vibranium::Session::do_write(std::size_t length) {
    auto self(shared_from_this());
    boost::asio::async_write(socket_, boost::asio::buffer(data_, length),
     [this, self](boost::system::error_code ec, std::size_t /*length*/)
     {
         if (!ec)
         {
             do_read();
         }
     });
}

这里是Session.h

#ifndef VIBRANIUM_CORE_SESSION_H
#define VIBRANIUM_CORE_SESSION_H

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>

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

namespace Vibranium{
    class Session: public std::enable_shared_from_this<Session>
    {
    public:
        Session(tcp::socket socket)
        : socket_(std::move(socket))
        {
        }
        void start();

    private:
        void do_read();
        void do_write(std::size_t length);
        tcp::socket socket_;
        enum { max_length = 1024 };
        char data_[max_length];
    };
}
#endif //VIBRANIUM_CORE_SESSION_H

这是我启动服务器的方式:

#include "Config.h"
#include "Database/MySQLConnection.h"
#include "Implementation/LoginDatabase.h"
#include "Banner.h"
#include "Server/Server.h"
#include <boost/asio.hpp>

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

int main() {
    //Don't mind Logger::FatalError it's just for coloring!
    Banner::Show(Logger::Error,"AuthServer");
    Config config("AuthServer");
    std::string defaultPort = "8080";
    MySQLConnectionInfo mySqlConnectionInfo(config, "LoginDatabaseInfo");
    LoginDatabaseConnection loginDatabaseConnection(mySqlConnectionInfo);
    loginDatabaseConnection.LoadDatabase();

    try
    {
        boost::asio::io_service io_service;
        Server s(io_service, std::stoi(config.GetConfigValue("AuthServerPort", defaultPort)));
        io_service.run();
    }
    catch (std::exception& e)
    {
        std::cerr << "Exception: " << e.what() << "\n";
    }

    return 0;
}

所以我在Server::do_accept() 中捕获了新连接,并且很可能在那里我必须填充所有客户端端点的向量。因此,在稍后阶段,我可以创建一个名为 Send 的函数发送到特定客户端,另一个名为 Broadcast 的函数发送到所有连接的客户端。

这里有两个问题:

  1. 包含所有连接的向量的类型应该是什么?我应该在哪里填写?
  2. 如何检测断开连接,以便从连接的客户端向量中删除客户端?

【问题讨论】:

    标签: c++ boost-asio


    【解决方案1】:

    1.包含所有连接的向量的类型应该是什么?我应该在哪里填写?

    您可以创建一个套接字向量来存储客户端:

    vector<tcp::socket> clients; // adding by clients.push_back(move(socket)); after accept'ing
    

    或者在套接字周围创建一些包装类并使用它,例如。

    class Client
    { 
       tcp::socket socket;
    public:
        Client (tcp::socket s) : socket{move(s)} {}
    ... some other logic
    

    并使用 vector&lt;Client&gt; 进行存储。

    2.如何检测断开连接,以便从连接的客户端向量中删除客户端?

    您可以使用第一次读取/写入套接字的失败作为连接断开的指示器,或者定期使用某种 KEEP ALIVE 消息作为 ping 消息来检测断开(或陈旧)的连接。

    【讨论】:

    • 谢谢。你能给出如何检测断开连接的代码示例吗?
    • 你可以看看这个example作为起点
    • 嘿@StPiere 我已经添加了Session.h 这是一个接近你建议的包装类吗?
    • 是的,基本上它应该适合。会话向量应该可以工作。
    • 在另一张纸条上。向量应该包含会话类型的指针还是只包含会话?我相信它应该是会话指针的向量,对吧?
    猜你喜欢
    • 2010-12-31
    • 1970-01-01
    • 2019-01-13
    • 1970-01-01
    • 2013-11-22
    • 1970-01-01
    • 2013-02-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多