Преобразование кода

Ниже приведена документация zabbix с форматом заголовка запроса. Документ Zabbix

У меня есть трудности с реализацией этого заголовка в C ++ (Arduino),

Я видел реализацию того , что мне нужно в этом форуме здесь, однако она на русском языке и реализована на C#, я пытался перевести ее, но безрезультатно.

Поэтому мне нужен кто-то, кто поможет мне написать функцию примеров заголовка в C ++ (Arduino).

Следует полный код Arduino после предложения @EdgarBonet изменить

#include <ArduinoJson.h>
#include <SPI.h>
#include <Ethernet.h>

// Config IP
IPAddress ip(192, 168, 0, 130);
IPAddress gw(192, 168, 0, 1);
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
float contador = 0;

EthernetClient client;

//Config Server address
const char* server = "192.168.0.135";
int porta = 10051;

void setup() {
    Serial.begin(9600);
    Ethernet.begin(mac, ip);
}

void loop() {
    // Begin Json
    const size_t capacity = JSON_ARRAY_SIZE(1)
                          + JSON_OBJECT_SIZE(2)
                          + JSON_OBJECT_SIZE(3);
    DynamicJsonBuffer jsonBuffer(capacity);

    JsonObject& root = jsonBuffer.createObject();
    root["request"] = "sender data";

    JsonArray& data = root.createNestedArray("data");

    JsonObject& data_0 = data.createNestedObject();
    data_0["host"] = "ethernet";
    data_0["key"] = "variavel1";
    data_0["value"] = contador;

    String json = "";
    root.printTo(json);

    const uint8_t *dataSend = (const uint8_t *) json.c_str();
    uint64_t data_length = json.length();
    uint8_t packet[13 + data_length];  // 13-byte header + payload

    // Write the 5-byte signature.
    memcpy(packet, "ZBXD\1", 5);

    // Add the 8-byte packet length, LSB first.
    for (int i = 0; i < 8; i++) {
        packet[5+i] = data_length >> 8*i;
    }

    // Add the payload.
    memcpy(packet + 13, dataSend, data_length);
    if (client.connect(server, porta)) {
        Serial.println("Enviando ao servidor");
        delay(1000);
        // Send the packet.
        client.write(packet, sizeof packet);
        delay(1000);
        contador ++;
    }
}

Следующий ответ сервера:

2034:20191003:101411.196 Message size 2066888786 from 192.168.0.130 exceeds the maximum size 1073741824 bytes. Message ignored.

, 👍-1

Обсуждение

Ваш код Arduino не компилируется. Пожалуйста, приведите нам Минимальный, воспроизводимый пример этой проблемы: https://stackoverflow.com/help/minimal-reproducible-example... Вы это видели: https://www.zabbix.com/integrations/arduino, @VE7JRO

Спасибо, что отредактировали свой вопрос. Когда я пытаюсь скомпилировать скетч, я получаю следующее сообщение об ошибке: DynamicJsonBuffer-это класс из ArduinoJson 5. Пожалуйста смотрите arduinojson.org/upgrade чтобы узнать, как обновить программу до ArduinoJson версии 6. Я не уверен, связано ли это с проблемой, с которой вы столкнулись, но вы можете подумать об обновлении библиотеки., @VE7JRO


1 ответ


0

Проблема довольно четко выражена в сообщении об ошибке:

ожидаемое значение 808529969 байт

Вы сказали серверу, что собираетесь предоставить ему 808529969 байт, но предоставили гораздо меньше. Почему вы сказали ему, что собираетесь отправить так много данных? Может быть, мы сможем получить ключ к разгадке, переписав это число в шестнадцатеричном формате:

808529969 = 0x30313031

Разбив это на отдельные байты, сначала LSB (так как именно этого ожидает сервер), у вас есть

0x31 0x30 0x31 0x30

Это байты, которые вы отправили на сервер, и все они являются кодами ASCII для цифр, которые составляют строку "1010". Я не знаю , как вам это пришло в голову, так как опубликованный вами код не является тем, который вы тестировали (опубликованный код даже не компилируется!). Но, похоже, в какой-то момент вы попытались преобразовать что-то в двоичный код ASCII, и действительно Строка(10, ЯЧЕЙКА) создает точно такую же строку, как указано выше.

Сервер ожидает, что длина данных будет представлена в виде двоичных байтов, а не в виде строки ASCII. Я лично стараюсь избегать строки класс, который может создать проблемы с памятью. В этой ситуации я бы просто работал с массивом байтов, набранным как uint8_t (так же, как у Arduino байтовый тип, только более стандартный). В приведенном ниже коде я для простоты предполагаю, что вы сохраняете строку для создания полезной нагрузки, но затем я переключаюсь на необработанный массив байтов:

const uint8_t *data = (const uint8_t *) json.c_str();
uint64_t data_length = json.length();
uint8_t packet[13 + data_length];  // 13-байтовый заголовок + полезная нагрузка

// Запишите 5-байтовую подпись.
memcpy(packet, "ZBXD\1", 5);

// Сначала добавьте 8-байтовую длину пакета, LSB.
for (int i = 0; i < 8; i++) {
    packet[5+i] = data_length >> 8*i;
}

// Добавьте полезную нагрузку.
memcpy(packet + 13, data, data_length);

// Отправьте пакет.
client.write(packet, sizeof packet);

Обратите внимание, что при работе с двоичными, а не текстовыми данными, вы должны использовать memcpy() вместо strcpy ()и client.write() вместо client.print().

,

Здравствуйте, мистер @EdgarBonet, сначала я хочу поблагодарить вас за помощь, наконец, я поместил ваш код в свой проект, но сервер сообщает об очередной ошибке, теперь говорит, что сообщение все еще слишком большое, согласно документации, это сообщение может иметь максимум 128 МБ, и согласно коду ошибки Размер сообщения 2066888786 от 192.168.0.130 превышает максимальный размер 1073741824 байта. Сообщение проигнорировано. `превышает этот лимит, так как у меня недостаточно репутации, чтобы ответить здесь, на форуме, я переслал весь свой код на [ссылку](http://dontpad.com/ardzabbixsenderiVBjuY7K)[/ссылка]. Благодарю, @Venicius Back

@VeniciusBack: У вас, вероятно, достаточно репутации, чтобы отредактировать свой вопрос. И вы все равно не захотите отвечать... если у вас нет ответа!, @Edgar Bonet

@VeniciusBack: Кроме того, когда вы предоставляете свой код и сообщаете об ошибке, дважды убедитесь, что сообщение об ошибке в вашем отчете сгенерировано _ точно такой же версией_ кода, который вы показываете. В противном случае вы напрасно тратите всеобщее время. Я почти уверен, что сообщение об ошибке и код, который вы показываете, не совпадают., @Edgar Bonet

Я отредактировал сообщение с полным кодом arduino, который я отправляю, и ответом на этот код, предоставленный сервером zabbix. Спасибо!, @Venicius Back

@VeniciusBack: Не редактируйте свой ответ, который был удален VE7JRO по очень веской причине (на самом деле это не ответ). Отредактируйте свой вопрос., @Edgar Bonet

Мистер @EdgarBonet, я хочу поблагодарить вас за всю помощь, наконец-то код сработал правильно, я внес изменения в ArduinoJson 6, спасибо вам за все терпение, которое вы проявили ко мне, вы проделали отличную работу, большое спасибо! Как я могу вам поверить или закрыть эту тему? Спасибо тебе еще раз! Крепкие объятия!, @Venicius Back

@VeniciusBack: Способ получить кредит - “принять” ответ., @Edgar Bonet