Mosquitto插槽读取错误的Arduino客户端 [英] Mosquitto socket read error Arduino client

查看:493
本文介绍了Mosquitto插槽读取错误的Arduino客户端的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚下载从GitHub最新的Arduino库code,它的打破了我的MQTT客户端程序。我使用的Arduino PubSubClient 1.91和Mosquitto 1.1.2(构建2013年3月7日)在Mac OSX。 (我还测试了反对Mosquitto在Windows 7上,同样的问题。)

I have just downloaded the latest Arduino Library code from Github, and it's broken my MQTT client program. I'm using PubSubClient 1.91 on Arduino, and Mosquitto 1.1.2 (Build 2013-03-07) on Mac OSX. (I also tested against Mosquitto on Windows 7, same problem.)

提供的Mosquitto客户做工精细,(苹果机到Windows时,Windows过到Mac),所以它的一些问题,什么是从Arduino的最终来临。一个Wireshark的跟踪显示Arduino的客户端发送以下数据包:

The supplied Mosquitto clients work fine, (Mac over to Windows, Windows over to Mac) so it's some problem with what's coming from the Arduino end. A wireshark trace shows the Arduino client sending the following data packet:

10:15:FF:FF:图4d:51:49:73:64:70:03:02:00:0F:00:07:41:72:64:75:69:6e中:1207米

10:15:ff:ff:4d:51:49:73:64:70:03:02:00:0f:00:07:41:72:64:75:69:6e:6f

而Mosquitto经纪人所示:
从10.0.0.115新建连接
套接字客户端(空)读取错误,断开。

And the Mosquitto broker shows: New connection from 10.0.0.115 Socket read error on client (null), disconnecting.

在我开始通过MQT​​T规范爬行,任何人都可以看到什么不对的数据包被发送?它一定是事做新的Arduino库code ...

Before I start to crawl through the MQTT spec, can anyone see anything wrong with the data packet being sent? It's got to be something to do with new Arduino library code...

* 的更新
经进一步调查,这似乎是一个code代问题AVR-G ++,虽然生活经验告诉我,它会变成并非如此。这里是code从PubSubClient.cpp片段

* Update Upon further investigation, it appears to be a code generation problem with avr-g++, although life experience tells me it will turn out not to be so. Here is a snippet of code from PubSubClient.cpp

boolean PubSubClient::connect(char *id, char *user, char *pass, char* willTopic,     uint8_t willQos, uint8_t willRetain, char* willMessage) {
   if (!connected()) {
      int result = 0;

      if (domain != NULL) {
        result = _client->connect(this->domain, this->port);
      } else {
        result = _client->connect(this->ip, this->port);
      }

      if (result) {
         nextMsgId = 1;
         uint8_t d[9] = { 0x00, 0x06, 'M','Q','I','s','d','p',MQTTPROTOCOLVERSION};
//         d[0] = 0;
//         d[1] = 6;
         Serial.print("d[0]="); Serial.println(d[0],HEX);

现在,Serial.print的结果略高于原来是0xFF的!因此,u​​int8_t有阵没有被正确初始化。 @knoleary您的指针坏FF字节导致我这一点。

Now, the result of the Serial.print just above turns out to be 0xFF !!! So, the uint8_t array is not being initialised correctly. @knoleary Your pointer to the bad FF bytes lead me to this.

如果我现在取消注释两行以上,并手动初始化前2个字节为0和6,一切工作正常,和我的程序与Mosquitto愉快地进行通信。

If I now uncomment the two lines above, and manually initialise the first 2 bytes to 0 and 6, all works fine, and my program communicates happily with Mosquitto.

我看了生成的code,但我不是专家爱特梅尔。

I've looked at the generated code, but I'm not an Atmel expert.

有没有人有任何线索,这可能是为什么?

Does anyone have any clue why this might be?

我使用的是从Arduino的1.05 AVR-G ++工具集,在Eclipse编译。

I'm compiling using the AVR-G++ toolset from Arduino 1.05, in Eclipse.

我要为一个啤酒!

推荐答案

OK,我发现它。这是一个相对微妙的错误。从本质上讲,当源$ C ​​$ C以下行编译;

OK, I found it. It's a relatively subtle bug. Essentially, when the following line of source code is compiled;

    uint8_t d[9] = { 0x00, 0x06, 'M','Q','I','s','d','p',MQTTPROTOCOLVERSION};

9字节获取存储在图像数据部分的常数。在运行时,小环复制9个字节到数组(D [])通过观察组合汇编/源列表中,我可以看到在数据部分被存储在9个字节的地方,然后打印出来定期,直到我发现了什么过分写他们。 (有点原始,我知道了!)

the 9 bytes get stored as a constant in the data section of the image. At runtime, a small loop copies the 9 bytes into the array (d[]) By looking at a combined Assembler / source listing, I could see where in the data section the 9 bytes were stored, and then print them out at regular intervals, until I found what was over-writing them. (A bit primitive, I know!)

原来,有一个在WiFi.cpp一个bug,Arduino的无线网络code。这里的code:

It turns out the there's a bug in WiFi.cpp , the Arduino WiFi code. Here's the code:

uint8_t WiFiClient::connected() {

  if (_sock == 255) {
    return 0;
  } else {
    uint8_t s = status();

    return !(s == LISTEN || s == CLOSED || s == FIN_WAIT_1 ||
                    s == FIN_WAIT_2 || s == TIME_WAIT ||
                    s == SYN_SENT || s== SYN_RCVD ||
                    (s == CLOSE_WAIT));
  }
}

原来,该_sock变量初始化其实像这样的:

It turns out the the _sock variable is actually initialised like this:

WiFiClient::WiFiClient() : _sock(MAX_SOCK_NUM) {
}

和MAX_SOCK_NUM是4,而不是255。所以,WiFiClient ::未使用的端口状态返回真实的,而不是假的。

and MAX_SOCK_NUM is 4, not 255. So, WiFiClient::status returned true, instead of false for an unused Socket.

这个方法被调用由MQTT客户是这样的:

This method was called by the MQTT Client like this:

boolean PubSubClient::connected() {
   boolean rc;
   if (_client == NULL ) {
      rc = false;
   } else {
      rc = (int)_client->connected();
      if (!rc) _client->stop();
   }
   return rc;
}

另外,由于_client->连接()方法返回的错误属实,_client_stop()方法被调用。这导致对一个不存在的插座阵列元件的写入,所以重写我的字符串数据。

And, since the _client->connected() method erroneously returned true, the _client_stop() method was called. This resulted in a write to a non-existent socket array element, and so overwrote my string data.

@knolleary,我想知道,有没有你的PubSubClient ::连接()方法断开任何具体的原因是什么?我用的是::连接方法在一个循环中,检查我还在相连,当然它导致我得到每轮循环断开/重新连接。任何机会,我们可以只让连接返回真/假,和处理断开的PuBSubClient ::连接?

@knolleary, I was wondering, is there any specific reason that your PubSubClient::connected() method does a disconnect? I use the ::connected method in a loop, to check that I'm still connected, and, of course it results in my getting a disconnect / reconnect each time round the loop. Any chance we could just make connected return true / false , and handle the disconnect in PuBSubClient::connect?

这篇关于Mosquitto插槽读取错误的Arduino客户端的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆