我在玩MQTT CONNECT消息。我有一个简单的C程序,它将打开指向笔记本电脑上运行的Mosquitto代理的TCP / IP套接字,发送MQTT CONNECT消息,(通常)接收4字节长的CONNACK答复,然后关闭套接字并退出程序。 >
当前,我不是建立自己的CONNECT消息,而是从Wireshark捕获中使用一条消息。



它可以导出为C数组,即MQTT。部分:

 char packet_bytes[] = {
  0x10, 0x20, 0x00, 0x06, 0x4d, 0x51, 0x49, 0x73,
  0x64, 0x70, 0x03, 0x02, 0x00, 0x3c, 0x00, 0x12,
  0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x31, 0x34, 0x38,
  0x35, 0x38, 0x39, 0x30, 0x38, 0x35, 0x37, 0x31,
  0x39, 0x34
};
 


使用此未修改的数组,一切正常,这是代理的输出:

 1486237905: New connection from 192.168.1.2 on port 1883.
1486237905: New client connected from 192.168.1.2 as root.1485890857194 (c1, k60).
1486237905: Sending CONNACK to root.1485890857194 (0, 0)
1486237905: Socket error on client root.1485890857194, disconnecting.
 



当我想修改客户端ID时问题就开始了在消息中。我最简单的尝试是从ID的结尾处切掉最后一个字符4

我认为这需要对实际代码进行三处修改。


删除最后一个数组中的0x34字节。
减少消息中的Remaining Length字段(数组中的第二个字节)。所以从32到31,0x20-> 0x1F
减少send函数的字节数参数。从34到33。(由于Header FlagsRemaining Length字段为+2)


 char packet_bytes[] = {
  0x10, 0x1F, 0x00, 0x06, 0x4d, 0x51, 0x49, 0x73,
  0x64, 0x70, 0x03, 0x02, 0x00, 0x3c, 0x00, 0x12,
  0x72, 0x6f, 0x6f, 0x74, 0x2e, 0x31, 0x34, 0x38,
  0x35, 0x38, 0x39, 0x30, 0x38, 0x35, 0x37, 0x31,
  0x39
};


if( send(s , packet_bytes , 33, 0) < 0)
{
    puts("Send failed");
    return 1;
}
 


它不起作用,这是代理的输出:

 1486239491: New connection from 192.168.1.2 on port 1883.
1486239491: Socket error on client <unknown>, disconnecting.
 



我知道Remaining Length字段需要特殊的编码,但不超过128。



我在这里错过了什么,我应该在Remaining Length字段旁边修改什么? br />

评论

代理是否不记录套接字错误代码或类似内容?

@ Aurora0001实际上,我没有进行检查,因为我认为详细的控制台日志记录会这样做。我将检查它,我必须在Windows下找到日志文件。

@ Aurora0001其实我很忙于在客户端发现错误,我还没有想到要搜索更详细的服务器日志,因此感谢您指出。如果发现有问题,我会进行更新。

目前我没有其他可用的日志。

@ Aurora0001不,发送数据,仅在这种情况下,我没有收到CONACK,recv函数返回0,程序退出。然后,我将尝试进行捕获。

#1 楼

我设法找到我的错误。我错误地认为客户端ID是一个修复字段,但它只是消息有效负载的一部分,因此需要一个长度前缀。根据规范:


CONNECT数据包的有效负载包含一个或多个带前缀的
字段,这些字段的存在由变量
标头中的标志确定。这些字段(如果存在)必须按以下顺序出现:客户
标识符,意愿主题,意愿消息,用户名,密码


,因此应在消息中再减少一个字节。正确的步骤:


从数组中删除最后一个字节0x34。
减少消息中的剩余长度字段(数组中的第二个字节)。因此,从32到31,是0x20-> 0x1F。
减少有效负载中客户端ID的长度前缀字节。在我的情况下,它是第16个字节(从1开始计数)0x12 ---> 0x11
递减send函数的字节数参数。从34到33。(+ 2,因为“标头标志”和“剩余长度”字段)

在此附加步骤之后,代理返回了CONNACK消息。