当前,我不是建立自己的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 Flags
和Remaining 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 /> #1 楼
我设法找到我的错误。我错误地认为客户端ID是一个修复字段,但它只是消息有效负载的一部分,因此需要一个长度前缀。根据规范:CONNECT数据包的有效负载包含一个或多个带前缀的
字段,这些字段的存在由变量
标头中的标志确定。这些字段(如果存在)必须按以下顺序出现:客户
标识符,意愿主题,意愿消息,用户名,密码
,因此应在消息中再减少一个字节。正确的步骤:
从数组中删除最后一个字节0x34。
减少消息中的剩余长度字段(数组中的第二个字节)。因此,从32到31,是0x20-> 0x1F。
减少有效负载中客户端ID的长度前缀字节。在我的情况下,它是第16个字节(从1开始计数)
0x12
---> 0x11
。递减send函数的字节数参数。从34到33。(+ 2,因为“标头标志”和“剩余长度”字段)
在此附加步骤之后,代理返回了CONNACK消息。
评论
代理是否不记录套接字错误代码或类似内容?@ Aurora0001实际上,我没有进行检查,因为我认为详细的控制台日志记录会这样做。我将检查它,我必须在Windows下找到日志文件。
@ Aurora0001其实我很忙于在客户端发现错误,我还没有想到要搜索更详细的服务器日志,因此感谢您指出。如果发现有问题,我会进行更新。
目前我没有其他可用的日志。
@ Aurora0001不,发送数据,仅在这种情况下,我没有收到CONACK,recv函数返回0,程序退出。然后,我将尝试进行捕获。