我的目标是能够发送大约150MB的文件超过mosquitto
.目前,这种转移的效率问题并不重要,只是为了了解这种转移是否可行.
MQTT规范提到消息负载限制为256MB,但我只能发送一个大小为4095KB的文件,仅此而已.发布器是用C蚊子库实现的,动态分配一个带有二进制数据的向量.发布程序不会遇到任何错误,但是在客户端发布数据后,如果发送的文件大于4065KB,则代理端不会出现发布通知,mosquitto_sub
也不会收到任何消息,但发生的是来自代理的消息,发布客户端成功断开连接:
1711360340: New connection from 127.0.0.1:50002 on port 1883.
1711360340: New client connected from 127.0.0.1:50002 as auto-A51C5B5B-F445-5952-5EA5-49B12F2E614D (p2, c1, k5).
1711360340: No will message specified.
1711360340: Sending CONNACK to auto-A51C5B5B-F445-5952-5EA5-49B12F2E614D (0, 0)
1711360340: Client auto-A51C5B5B-F445-5952-5EA5-49B12F2E614D disconnected: Success.
真的有可能发送超过mosquitto
个大文件吗?如果是,执行方面的最佳做法是什么?
编辑:删除文件源代码
#include <cstdio>
#include <mosquitto.h>
#include <iostream>
#include <fstream>
#include <vector>
#include <memory>
struct mosquitto *mosq;
void publishImage(const char *topic, const char *image_path)
{
std::ifstream fs(image_path, std::ios::in | std::ios::binary | std::ios::app);
std::unique_ptr<std::vector<uint8_t>> v_buf;
void *msgPayload = nullptr;
int msgPayloadLen;
if (fs.good())
{
v_buf.reset(new std::vector<uint8_t>((std::istreambuf_iterator<char>(fs)), (std::istreambuf_iterator<char>())));
fs.close();
msgPayload = static_cast<void*>(v_buf.get()->data());
msgPayloadLen = v_buf.get()->size();
}
if(msgPayload == nullptr)
{
fprintf(stderr, "image could not be copied to memory\n");
return;
}
int rc = mosquitto_publish(mosq, NULL, topic, msgPayloadLen, msgPayload, 1, false);
if (rc != MOSQ_ERR_SUCCESS)
{
fprintf(stderr, "mosquitto publish error: %s\n", mosquitto_strerror(rc));
}
return;
};
int main(int argc, const char* argv[])
{
if (argc < 2)
{
fprintf(stderr, "Not enough input arguments!\nUsage: imageUpdater <topic> <path_to_image>\n");
return 1;
}
const char *topic = argv[1];
const char *pathToImage = argv[2];
mosquitto_lib_init();
mosq = mosquitto_new(NULL, true, NULL);
if (mosq == NULL)
{
fprintf(stderr, "Error: Out of memory.\n");
return 1;
}
int rc = mosquitto_connect(mosq, "127.0.0.1", 1883, 5);
if (rc != MOSQ_ERR_SUCCESS)
{
mosquitto_destroy(mosq);
fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
return 1;
}
else
{
printf("Connected!\n");
}
rc = mosquitto_loop_start(mosq);
if (rc != MOSQ_ERR_SUCCESS)
{
mosquitto_destroy(mosq);
fprintf(stderr, "Error: %s\n", mosquitto_strerror(rc));
return 1;
}
publishImage(topic, pathToImage);
mosquitto_lib_cleanup();
return 0;
}
EDIT2:成功发布的日志(log)输出(小文件)
1711376922: New client connected from 127.0.0.1:38426 as auto-33E25100-81EB-0583-E540-C73A5D29E267 (p2, c1, k5).
1711376922: No will message specified.
1711376922: Sending CONNACK to auto-33E25100-81EB-0583-E540-C73A5D29E267 (0, 0)
1711376922: Received PUBLISH from auto-33E25100-81EB-0583-E540-C73A5D29E267 (d0, q1, r0, m1, 'fota/update', ... (4192256 bytes))
1711376922: Sending PUBACK to auto-33E25100-81EB-0583-E540-C73A5D29E267 (m1, rc0)
1711376922: Client auto-33E25100-81EB-0583-E540-C73A5D29E267 closed its connection.
使用QOS0代替QOS1使传输更大的文件成为可能,但可靠性较低.10MB文件传输成功,但仅在第5次try 时才成功.实际再查,QOS1在多次try 后,也成功传输了10MB的文件.对于4000KB左右的文件,QOS0的可靠性不如QOS1.