C++ Boost ASIO-无法通过TCP发送消息

C++ Boost ASIO-无法通过TCP发送消息,c++,boost-asio,C++,Boost Asio,我正在使用Boost ASIO进行TCP网络通信。这是我的密码: Server.h: #ifndef VIBRANIUM_CORE_SERVER_H #define VIBRANIUM_CORE_SERVER_H #include <cstdlib> #include <iostream> #include <memory> #include <utility> #include <boost/asio.hpp> #include &l

我正在使用Boost ASIO进行TCP网络通信。这是我的密码:

Server.h

#ifndef VIBRANIUM_CORE_SERVER_H
#define VIBRANIUM_CORE_SERVER_H
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>
#include <deque>
#include "Logger.h"
#include "Client.h"
#include "Protocol/ServerOpcode.h"

using boost::asio::ip::tcp;
namespace Vibranium {
    class Server {
    public:
        Server(boost::asio::io_service &io_service, short port)
                : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
                  socket_(io_service) {
            do_accept();
            Logger::Log("Server Started! Listening on Port("+std::to_string(port)+")", Logger::Success, true);
        }
        static std::deque<std::shared_ptr<Client>> Clients;

    private:
        void do_accept();
        int incrementor;
        tcp::acceptor acceptor_;
        tcp::socket socket_;
    };

}


#endif //VIBRANIUM_CORE_SERVER_H
#ifndef VIBRANIUM_CORE_CLIENT_H
#define VIBRANIUM_CORE_CLIENT_H

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>
#include "Protocol/ServerOpcode.h"

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

namespace Vibranium{
    class Client: public std::enable_shared_from_this<Client>
    {
    public:
        Client(tcp::socket socket)
        : socket(std::move(socket))
        {
        }
        void start();
        int connectionId;
        tcp::socket socket;
        void Send(ServerOpcode serverOpcode, const std::string& message);

    private:
        void do_read();
        void do_write(std::size_t length);
        enum { max_length = 1024 };
        char data_[max_length];
    };
}
#endif //VIBRANIUM_CORE_CLIENT_H
Client.h

#ifndef VIBRANIUM_CORE_SERVER_H
#define VIBRANIUM_CORE_SERVER_H
#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>
#include <deque>
#include "Logger.h"
#include "Client.h"
#include "Protocol/ServerOpcode.h"

using boost::asio::ip::tcp;
namespace Vibranium {
    class Server {
    public:
        Server(boost::asio::io_service &io_service, short port)
                : acceptor_(io_service, tcp::endpoint(tcp::v4(), port)),
                  socket_(io_service) {
            do_accept();
            Logger::Log("Server Started! Listening on Port("+std::to_string(port)+")", Logger::Success, true);
        }
        static std::deque<std::shared_ptr<Client>> Clients;

    private:
        void do_accept();
        int incrementor;
        tcp::acceptor acceptor_;
        tcp::socket socket_;
    };

}


#endif //VIBRANIUM_CORE_SERVER_H
#ifndef VIBRANIUM_CORE_CLIENT_H
#define VIBRANIUM_CORE_CLIENT_H

#include <cstdlib>
#include <iostream>
#include <memory>
#include <utility>
#include <boost/asio.hpp>
#include "Protocol/ServerOpcode.h"

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

namespace Vibranium{
    class Client: public std::enable_shared_from_this<Client>
    {
    public:
        Client(tcp::socket socket)
        : socket(std::move(socket))
        {
        }
        void start();
        int connectionId;
        tcp::socket socket;
        void Send(ServerOpcode serverOpcode, const std::string& message);

    private:
        void do_read();
        void do_write(std::size_t length);
        enum { max_length = 1024 };
        char data_[max_length];
    };
}
#endif //VIBRANIUM_CORE_CLIENT_H
以下是我如何模拟与服务器的几个连接:

Config config("AuthServer");
std::string defaultIP   = "127.0.0.1";
std::string defaultPort = "8080";
int connectionsNumber   = CommandQuestion<int>::AskQuestion("How many connections do you want established?");
std::cout << "Initializing " << std::to_string(connectionsNumber) << " connection/s." << std::endl;

std::cout << "Trying to connect to  " <<  defaultIP << " on port: " << config.GetConfigValue("AuthServerPort", defaultPort)  << std::endl;
boost::asio::io_context io_context;
std::vector<tcp::socket> sockets;
for (int i = 0; i < connectionsNumber; ++i) {
    try
    {
        sockets.emplace_back(io_context);
        tcp::socket& s{sockets.back()};
        tcp::resolver resolver(io_context);
        boost::asio::connect(s, resolver.resolve( defaultIP,config.GetConfigValue("AuthServerPort", defaultPort)));

        std::string message = "I am testing here!!!";
        size_t request_length = std::strlen(message.c_str());
        boost::asio::write(s, boost::asio::buffer(message, request_length));

        char reply[max_length];
        size_t reply_length = boost::asio::read(s,boost::asio::buffer(reply, request_length));
        Logger::Log(std::to_string(i) + " Connected!",Logger::Success);
                std::cout << "Reply is: ";
                std::cout.write(reply, reply_length);
                std::cout << "\n";
    }
    catch (std::exception& e)
    {
        std::cerr << "Exception: " << e.what() << "\n";
    }
Config配置(“AuthServer”);
std::string defaultIP=“127.0.0.1”;
std::string defaultPort=“8080”;
int connectionsNumber=CommandQuestion::AskQuestion(“您希望建立多少个连接?”);

std::cout我发现了错误所在,下面是我解决问题的方法:

void Vibranium::Client::Send(ServerOpcode serverOpcode, const std::string& message) {
    auto self(shared_from_this());
    std::cout << "HERE!" << std::endl;
    strcpy(data_, message.c_str());
    size_t request_length = sizeof(data_)/sizeof(*data_);
    boost::asio::async_write(socket, boost::asio::buffer(data_, request_length),
     [this, self](boost::system::error_code ec, std::size_t /*length*/)
     {
         if (ec)
             Logger::Log("Message sent failed to " + std::to_string(connectionId),Logger::Error);
     });
}
void Vibranium::Client::Send(ServerOpcode ServerOpcode,const std::string&message){
自动自我(从_this()共享_);

std::cout不确定,但
async_write(socket,boost::asio::buffer(message.c_str(),…
in
Vibranium::Client::Send
看起来可疑。message.c_str()返回的以null结尾的字符串
可能在
异步写入
完成之前变得无效。从有关
缓冲区
参数的文档中:
“…调用方保留底层内存块的所有权,这必须保证它们在调用处理程序之前保持有效。”