提问者:小点点

我不知道为什么使用boost asio的代码会导致错误


我创建了主cpp文件和三个类来创建异步服务器。 分别为serverserviceacceptor。 但是,它们导致了生成过程中的错误,即使visual studio 2019环境中没有错误。 我试图修复错误,但大多数错误都发生在其他文件中,所以我自己都想不起来。

#include "Server.h"
#include <iostream>
#include <boost/asio.hpp>
#include <thread>
#include <atomic>
#include <memory>
#define DEFAULT_THREAD_SIZE 2;
using namespace boost;
int main()
{
 unsigned short port_num;
    std::cin >> port_num;
    try {
        Server srv;
        unsigned int threads = std::thread::hardware_concurrency() * 2;
        if (threads == 0) {
            threads = DEFAULT_THREAD_SIZE;
        }
        std::cout << "\nPort - " << port_num << "\nServer start\n";
        srv.Start(port_num, threads);
        while (1) {
            std::cin >> srv;
        }
    }
    catch (system::system_error& e) {
        std::cout << "\nError code: " << e.code() << "\nError Message\n" << e.what();
    }
    return 0;
}

这包括Server.h,它定义了服务器类。

#include "Acceptor.h"
#include <boost/asio.hpp>
#include <thread>
#include <atomic>
#include <memory>
using namespace boost;
class Server
{
public:
    Server();
    void Start(unsigned short port_num, unsigned int threads);
    void Stop();
    int Command(std::string& str);
private:
    asio::io_service mios;
    std::unique_ptr<asio::io_service::work> mWork;
    std::unique_ptr<Acceptor> mAcceptor;
    std::vector <std::unique_ptr<std::thread>> mThreads;
};

std::istream& operator>>(std::istream& is, Server& srv);

下面是实现,server.cpp。

#include "Server.h"
Server::Server() {
    mWork.reset(new asio::io_service::work(mios));
}
void Server::Start(unsigned short port_num, unsigned int threads) {
    assert(thread > 0);
    mAcceptor.reset(new Acceptor(mios, port_num));
    mAcceptor->Start();
    for (int i = 0; i < threads; i++) {
        std::unique_ptr<std::thread> th(new std::thread([this]() {mios.run(); }));
        mThreads.push_back(std::move(th));
    }
}
void Server::Stop() {
    mAcceptor->Stop();
    mios.stop();

    for (auto& th : mThreads) {
        th->join();
    }
}
int Server::Command(std::string& str) {
    return 0;
}
std::istream& operator>>(std::istream& is, Server& srv) {
    std::string str;
    is >> str;
    srv.Command(str);
    return is;
}

这是Acceptor类。

#include "Service.h"
#include <boost/asio.hpp>
#include <thread>
#include <atomic>
#include <memory>
using namespace boost;
class Acceptor
{
public:
    Acceptor(asio::io_service& ios, unsigned short port_num);
    void Start();
    void Stop();
private:
    std::shared_ptr<asio::io_service> mios;
    std::shared_ptr<asio::ip::tcp::acceptor> mAcceptor;
    std::atomic<bool> mIsStopped;
    void InitAccept();
    void OnAccept(const system::error_code ec, std::shared_ptr<asio::ip::tcp::socket> sock);
};
#include "Acceptor.h"
Acceptor::Acceptor(asio::io_service& ios, unsigned short port_num) {
    mios = std::make_shared<asio::io_service>(ios);
    mAcceptor = std::make_shared<asio::ip::tcp::acceptor>(mios, asio::ip::tcp::endpoint(asio::ip::address_v4::any(), port_num));
    mIsStopped = false;
}
void Acceptor::Start() {
    mAcceptor->listen();
    InitAccept();
}
void Acceptor::Stop() {
    mIsStopped.store(true);
}

void Acceptor::InitAccept() {
    std::shared_ptr<asio::ip::tcp::socket> sock(new asio::ip::tcp::socket(mios));
    mAcceptor->async_accept(*sock, [this, sock](const system::error_code& error) {OnAccept(error, sock);});
}
void Acceptor::OnAccept(const system::error_code ec, std::shared_ptr<asio::ip::tcp::socket> sock) {
    if (ec.value() == 0 || ER) {
        (new Service(sock))->StartHandling();
    }
    else{
        std::cout << "Error code:" << ec.value() << "error " << "Error message: " << ec.message() << "\n";
    }
    if (!mIsStopped.load()) {
        InitAccept();
    }
    else {
        mAcceptor->close();
    }
}

服务类

#define ER true
#include <iostream>
#include <boost/asio.hpp>
#include <thread>
#include <atomic>
#include <memory>
using namespace boost;
class Service
{
public:
    Service(std::shared_ptr<asio::ip::tcp::socket> sock);
    void StartHandling();
private:
    void OnRequestReceived(const boost::system::error_code& ec, std::size_t bytes_transferred);
    std::string mReponse;
    std::shared_ptr<asio::ip::tcp::socket> mSock;
    asio::streambuf mRequest;
    void OnReponseSent(const system::error_code& ec, std::size_t bytes_transferred);

    void OnFinish();
    std::string ProcessRequest(asio::streambuf& request);
};
#include "Service.h"
Service::Service(std::shared_ptr<asio::ip::tcp::socket> sock){
    mSock = sock;
}
void Service::StartHandling() {
    asio::async_read_until(mSock, mRequest, '\n', [this](const system::error_code ec, std::size_t bytes_transferred) {OnRequestReceived(ec, bytes_transferred); });
}

void Service::OnRequestReceived(const system::error_code& ec, std::size_t bytes_transferred) {
    if (ec.value() != 0 || ER) {
        std::cout << "Error code:" << ec.value() << "Error message: " << ec.message() << "\n";
        OnFinish();
        return;
    }
    mReponse = ProcessRequest(mRequest);
    asio::async_write(mSock, asio::buffer(mReponse), [this](const system::error_code& ec, std::size_t bytes_transferred) {OnReponseSent(ec, bytes_transferred); });
}

void Service::OnReponseSent(const system::error_code& ec, std::size_t bytes_transferred) {
    if (ec.value() != 0 || ER) {
        std::cout << "Error code:" << ec.value() << "Error message: " << ec.message() << "\n";
    }
    OnFinish();
}

void Service::OnFinish() {
    delete this;
}
std::string Service::ProcessRequest(asio::streambuf& request) {
    std::string reponse;
    std::istream input(&request);
    std::getline(input, reponse);
    assert(reponse.back() == '\n');
    return reponse;
}

我不知道该怎么办。 我想自己做,但我连调试都做不到,因为我搞不清楚问题出在哪里,而且它没有构建。


共1个答案

匿名用户

它根本无法编译。 我真的很想知道,人们怎么能在注意到这些东西不编译之前就想出/这么多/代码。

规则1:小步走(这对专业人士也同样适用,只是他们把它内化了而已)。

你在做一些事情,比如:

mios = std::make_shared<asio::io_service>(ios);

这要求IO_service是可复制的(实际情况并非如此)。 您可能会将MIOS作为引用:

asio::io_service& mios;

对shared_ptr的“迷信”使用似乎随处可见。

事实是…

assert(thread > 0);

拼写错误的threads表示您可能正在生成仅限发行版的生成。

void Service::StartHandling() {
    asio::async_read_until(mSock, mRequest, '\n', [this](const system::error_code ec, std::size_t bytes_transferred) {OnRequestReceived(ec, bytes_transferred); });
}

这会触发错误:

/home/sehe/custom/boost_1_73_0/boost/asio/impl/read_until.hpp|959 col 53| error: no type named ‘executor_type’ in ‘class std::shared_ptr<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >’

显然您指的是*msock。 以后相同:

asio::async_write(*mSock, asio::buffer(mReponse), [this](const system::error_code& ec, std::size_t bytes_transferred) {OnReponseSent(ec, bytes_transferred); });

指针不是它所指向的对象--即使是智能指针也不是。 智能指针的意义[原文如此]不是让C++等同于(比如说)Java--如果你想要的话,你应该使用Java。

通过这些,它编译了:Live On Wandbox