eclipse / paho.mqtt.cpp

Other
1.01k stars 432 forks source link

Can not run subscription!Info:0x00007FFB16EFCF19 处(位于 mqtt_install_test_vs.exe 中)有未经处理的异常: Microsoft C++ 异常: std::bad_alloc,位于内存位置 0x000000B68D9AE370 处。 #501

Open ShuiYunXi opened 3 months ago

ShuiYunXi commented 3 months ago

I used had compiled the paho-maqtt-cpp lib with OpenSSL,I can not use the lib to test on vs2022!! this is info: code:

#include <iostream>
#include <cstdlib>
#include <string>
#include <cstring>
#include <cctype>
#include <thread>
#include <chrono>
#include "mqtt/async_client.h"

const std::string SERVER_ADDRESS("tcp://broker.emqx.io:1883");
const std::string CLIENT_ID("exampleclientsub");

const std::string TOPIC("test");

const int   QOS = 1;
const int   N_RETRY_ATTEMPTS = 5;

/////////////////////////////////////////////////////////////////////////////

// Callbacks for the success or failures of requested actions.
// This could be used to initiate further action, but here we just log the
// results to the console.

class action_listener : public virtual mqtt::iaction_listener
{
    std::string name_;

    void on_failure(const mqtt::token& tok) override {
        std::cout << name_ << " failure";
        if (tok.get_message_id() != 0)
            std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl;
        std::cout << std::endl;
    }

    void on_success(const mqtt::token& tok) override {
        std::cout << name_ << " success";
        if (tok.get_message_id() != 0)
            std::cout << " for token: [" << tok.get_message_id() << "]" << std::endl;
        auto top = tok.get_topics();
        if (top && !top->empty())
            std::cout << "\ttoken topic: '" << (*top)[0] << "', ..." << std::endl;
        std::cout << std::endl;
    }

public:
    action_listener(const std::string& name) : name_(name) {}
};

/////////////////////////////////////////////////////////////////////////////

/**
 * Local callback & listener class for use with the client connection.
 * This is primarily intended to receive messages, but it will also monitor
 * the connection to the broker. If the connection is lost, it will attempt
 * to restore the connection and re-subscribe to the topic.
 */
class callback : public virtual mqtt::callback,
    public virtual mqtt::iaction_listener

{
    // Counter for the number of connection retries
    int nretry_;
    // The MQTT client
    mqtt::async_client& cli_;
    // Options to use if we need to reconnect
    mqtt::connect_options& connOpts_;
    // An action listener to display the result of actions.
    action_listener subListener_;

    // This deomonstrates manually reconnecting to the broker by calling
    // connect() again. This is a possibility for an application that keeps
    // a copy of it's original connect_options, or if the app wants to
    // reconnect with different options.
    // Another way this can be done manually, if using the same options, is
    // to just call the async_client::reconnect() method.
    void reconnect() {
        std::this_thread::sleep_for(std::chrono::milliseconds(2500));
        try {
            cli_.connect(connOpts_, nullptr, *this);
        }
        catch (const mqtt::exception& exc) {
            std::cerr << "Error: " << exc.what() << std::endl;
            exit(1);
        }
    }

    // Re-connection failure
    void on_failure(const mqtt::token& tok) override {
        std::cout << "Connection attempt failed" << std::endl;
        if (++nretry_ > N_RETRY_ATTEMPTS)
            exit(1);
        reconnect();
    }

    // (Re)connection success
    // Either this or connected() can be used for callbacks.
    void on_success(const mqtt::token& tok) override {}

    // (Re)connection success
    void connected(const std::string& cause) override {
        std::cout << "\nConnection success" << std::endl;
        std::cout << "\nSubscribing to topic '" << TOPIC << "'\n"
            << "\tfor client " << CLIENT_ID
            << " using QoS" << QOS << "\n"
            << "\nPress Q<Enter> to quit\n" << std::endl;

        cli_.subscribe(TOPIC, QOS, nullptr, subListener_);
    }

    // Callback for when the connection is lost.
    // This will initiate the attempt to manually reconnect.
    void connection_lost(const std::string& cause) override {
        std::cout << "\nConnection lost" << std::endl;
        if (!cause.empty())
            std::cout << "\tcause: " << cause << std::endl;

        std::cout << "Reconnecting..." << std::endl;
        nretry_ = 0;
        reconnect();
    }

    // Callback for when a message arrives.
    void message_arrived(mqtt::const_message_ptr msg) override {
        std::cout << "Message arrived" << std::endl;
        std::cout << "\ttopic: '" << msg->get_topic() << "'" << std::endl;
        std::cout << "\tpayload: '" << msg->to_string() << "'\n" << std::endl;
    }

    void delivery_complete(mqtt::delivery_token_ptr token) override {}

public:
    callback(mqtt::async_client& cli, mqtt::connect_options& connOpts)
        : nretry_(0), cli_(cli), connOpts_(connOpts), subListener_("Subscription") {}
};

/////////////////////////////////////////////////////////////////////////////

int main(int argc, char* argv[])
{
    // A subscriber often wants the server to remember its messages when its
    // disconnected. In that case, it needs a unique ClientID and a
    // non-clean session.
    try {
        mqtt::async_client cli(SERVER_ADDRESS, CLIENT_ID);

        mqtt::connect_options connOpts;
        connOpts.set_clean_session(false);

        // Install the callback(s) before connecting.
        callback cb(cli, connOpts);
        cli.set_callback(cb);

        // Start the connection.
        // When completed, the callback will subscribe to topic.

        std::cout << "Connecting to the MQTT server..." << std::flush;
        cli.connect(connOpts, nullptr, cb);
    }
    catch (const mqtt::exception& exc) {
        std::cerr << "\nERROR: Unable to connect to MQTT server: '"
            << SERVER_ADDRESS << "'" << exc << std::endl;
        return 1;
    }

    // Just block till user tells us to quit.

    while (std::tolower(std::cin.get()) != 'q')
        ;

    // Disconnect

    /*try {
        std::cout << "\nDisconnecting from the MQTT server..." << std::flush;
        cli.disconnect()->wait();
        std::cout << "OK" << std::endl;
    }
    catch (const mqtt::exception& exc) {
        std::cerr << exc << std::endl;
        return 1;
    }*/

    return 0;
}

fatal error image: image image

server test image: image install library info : image image image

I tried a number of ways, including recompiling the library and using official routines, but the mqtt::async_client cli(SERVER_ADDRESS, CLIENT_ID); This code error, or memory allocation error, or throw exception prompt string error, please help me solve, thank you

fpagliughi commented 3 months ago

It's really hard to tell what's happening here, with pieces of code missing and others formatted in lots of different styles.

It might be helpful if you can reduce this down to a minimal example that fails, posted in a text code block. This should be pretty small, since it seems to be failing right on the client construction.

But the error from the console is pretty clear. The library is claiming that you're giving it a string that is not UTF-8. Are you using Unicode or wide char strings? Sorry I don't know much about Windows and MSVS, and how it is configured.

ShuiYunXi commented 3 months ago

ok,I built a simplest case. The function of this case is to create a client. I tried to let it print some messages to help me analyze the cause of the problem, but still failed. The code is as follows:

#include <iostream>
#include <string>
#include "mqtt/async_client.h"

const std::string SERVER_ADDRESS("tcp://broker.emqx.io:1883");
const std::string CLIENT_ID("example_client");

int main() {
    try {
        std::cout << "Creating MQTT client..." << std::endl;
        mqtt::async_client cli(SERVER_ADDRESS, CLIENT_ID);
        std::cout << "MQTT client created successfully." << std::endl;

        mqtt::connect_options connOpts;
        connOpts.set_clean_session(true);

        std::cout << "Connecting to the MQTT server..." << std::flush;
        auto connToken = cli.connect(connOpts);
        connToken->wait();
        std::cout << "Connected!" << std::endl;

        std::cout << "Disconnecting from the MQTT server..." << std::flush;
        cli.disconnect()->wait();
        std::cout << "Disconnected!" << std::endl;

    }
    catch (const mqtt::exception& exc) {
        std::cerr << "MQTT exception: " << exc.what() << std::endl;
        return 1;
    }
    catch (const std::exception& exc) {
        std::cerr << "Standard exception: " << exc.what() << std::endl;
        return 1;
    }
    catch (...) {
        std::cerr << "Unknown exception occurred." << std::endl;
        return 1;
    }

    return 0;
}

The program running results are as follows: image Note that I have successfully added and built the paho-mqtt3as.lib and paho-mqttpp3.lib libraries to my project, and I can run the server using the paho-mqtt-c version. But this exception still exists. The C++ library version I use is 1.4.0, and the C library version is: 1.3.13. I am not sure if there is any conflict between the two libraries. I hope to get your help. Thank you.

ShuiYunXi commented 3 months ago

OK,I have been Sovled the fatal error! this is a Bug in 1.4.0version.Because I rolled back the code to 1.3.2, the previous version, and rebuilt from the source, the issue was resolved. My code as follow:

#include <iostream>
#include <string>
#include "mqtt/async_client.h"

const std::string SERVER_ADDRESS("tcp://broker.emqx.io:1883");
const std::string CLIENT_ID("example_client");

int main() {
    try {
        std::cout << "Creating MQTT client..." << std::endl;
        mqtt::async_client cli(SERVER_ADDRESS, CLIENT_ID);
        std::cout << "MQTT client created successfully." << std::endl;

        mqtt::connect_options connOpts;
        connOpts.set_clean_session(true);

        std::cout << "Connecting to the MQTT server..." << std::flush;
        auto connToken = cli.connect(connOpts);
        connToken->wait();
        std::cout << "Connected!" << std::endl;

        std::cout << "Disconnecting from the MQTT server..." << std::flush;
        cli.disconnect()->wait();
        std::cout << "Disconnected!" << std::endl;

    }
    catch (const mqtt::exception& exc) {
        std::cerr << "MQTT exception: " << exc.what() << std::endl;
        return 1;
    }
    catch (const std::exception& exc) {
        std::cerr << "Standard exception: " << exc.what() << std::endl;
        return 1;
    }
    catch (...) {
        std::cerr << "Unknown exception occurred." << std::endl;
        return 1;
    }

    return 0;
}

and it's run of result as follow: image

Hopefully this information gives you some ideas on how to fix this BUG. Thank you very much for your help