【问题标题】:Mosquitto Broker is receving data partiallyMosquitto Broker 正在接收部分数据
【发布时间】:2015-06-22 11:45:08
【问题描述】:

我正在尝试向 mosquitto MQTT 代理发送连接数据包。我可以与代理建立连接,但代理没有完全接收连接数据,即,wireshark 没有在代理中显示 MQIspd 数据,而是接收客户端 ID。

MQTT 协议版本为 v3.0。

通过 SIM900 GSM/GPRS 调制解调器发送数据包。

代码有什么问题?

下面是连接包C代码:

#define MQTTCONNECT 1<<4
#define MQTTPUBLISH 3<<4
#define KEEPALIVE 15000

int main()
{
    uint8_t buf[255];
    char *id="MQTT"
    uint8_t var_header[] = {0x00,0x06,0x4d,0x51,0x49,0x73,0x64,0x70,0x03,0x02,0x00,KEEPALIVE/500,0x00,strlen(id);
    uint8_t fixed_header[] = {MQTTCONNECT,12+strlen(id)+2};
    char packet[sizeof(fixed_header)+sizeof(var_header)+strlen(id)];

    memset(packet,0,sizeof(packet));
    memcpy(packet,fixed_header,sizeof(fixed_header));
    //memcpy(packet+sizeof(fixed_header),var_header,sizeof(var_header));
    //memcpy(packet+sizeof(fixed_header)+sizeof(var_header),id,strlen(id));
    //sprintf(buf,"%s\x1A",memcpy(packet+sizeof(fixed_header)+sizeof(var_header),id,strlen(id));
    sprintf(buf,"%s\x1A",memcpy(packet+sizeof(fixed_header)+sizeof(var_header),id,strlen(id)));
    port_write(buf); //write data into the serial port.
    return 0;
}

谢谢。

【问题讨论】:

    标签: c mqtt gprs


    【解决方案1】:

    正如@ralight 所说,使用 sprintf 中的 memcpy,您只需将消息的有效负载复制到 buf 中(您不会复制固定标头和可变标头),在这种情况下,有效负载仅包含客户端 ID。 但是我同意@ralight ...两个“缓冲区”没有用。

    【讨论】:

      【解决方案2】:

      您的port_write(buf) 将从packet 变量中写入数据,该变量从packet[sizeof(fixed_header)+sizeof(var_header)] 开始。这就是sprintf() 调用复制到buf 的内容,当然这不是您想要的。我认为不需要同时拥有 packetbuf 变量,只需使用其中一个,我认为这会简化问题。

      试试这个:

      int main()
      {
          char *id="MQTT"
          uint8_t var_header[] = {0x00, 0x06, 0x4d, 0x51, 0x49, 0x73, 0x64, 0x70, 0x03, 0x02, 0x00, KEEPALIVE/500, 0x00, strlen(id);
          uint8_t fixed_header[] = {MQTTCONNECT, 12+strlen(id)+2};
          char packet[sizeof(fixed_header)+sizeof(var_header)+strlen(id) + 2];
      
          memset(packet, 0, sizeof(packet));
          memcpy(packet, fixed_header, sizeof(fixed_header));
          memcpy(packet+sizeof(fixed_header), var_header, sizeof(var_header));
          sprintf(packet+sizeof(fixed_header)+sizeof(var_header), "%s\x1A", id);
      
          port_write((uint8_t *)packet); //write data into the serial port.
      
          return 0;
      }
      

      【讨论】:

      • 感谢您的回复。我使用 sprintf 的原因是我想将数据发送到串行,所以我需要将数据与“x1A”字符串一起写入。我不能简单地给出 'port_write(packet);'。
      • 关键是您的 sprintf 调用意味着您最终发送了错误的数据。 sprintf 本身不是罪魁祸首,只是数据放错了地方。
      • 谢谢@ralight。我在这里面临另一个问题。在 'var_header' 数组中 0x00 值会产生问题。当我从该数组中删除该值并运行代码时,代理会收到“MQIsdp”。否则代理不会收到任何数据。
      • 这是 port_write() 的问题,然后从事物的声音来看,它也需要接受“长度”参数。您不能合法地删除 0x00 值。
      • 这不是真正讨论的地方,但重点是printf() 和大概port_write() 假设一个以零结尾的字符串。如果您的字符串以零开头,那么他们将假定没有要打印的数据。您需要使用不同的函数来输出数据。 fwrite() 允许您指定正在写入的数据的长度,例如。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-02-23
      • 1970-01-01
      相关资源
      最近更新 更多