首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用WiFi盾的Arduino发出奇怪的post请求

使用WiFi盾的Arduino发出奇怪的post请求
EN

Stack Overflow用户
提问于 2016-09-02 14:17:50
回答 1查看 232关注 0票数 0

我正在做基于Arduino Uno的小型气象站的工作。事实上,我已经创建了一个原型,可以测量CO2的湿度、温度、压力和水平,并将数据通过POST请求发送到服务器。整整一周,它以每小时的方式将数据完美地发送到服务器。但昨天我发现没有新的数据。我的第一个想法是WiFi出了点问题,我重新启动路由器,检查连接情况,一切都很完美。我认为如果Arduino出了什么问题并重新启动它,它就能工作。因此,我检查连接后得到了什么,并回答如下:

代码语言:javascript
运行
复制
   HTTP/1.1 405 METHOD NOT ALLOWED
   Date: Fri, 02 Sep 2016 13:27:02 GMT
   Server: Apache/2.4.10 (Debian)
   Allow: GET, OPTIONS, POST, HEAD
   Content-Length: 178
   Connection: close
   Content-Type: text/html

   <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
   <title>405 Method Not Allowed</title>
   <h1>Method Not Allowed</h1>
   <p>The method is not allowed for the requested URL.</p>
   *CLOS*

好的,然后我发送邮件请求到服务器手动(槽邮递员),这是工作。所以我去服务器并启动读取日志,没有错误,但是在access.log中我发现了一些有趣的东西:

邮递员发来的工作邮件请求如下:

代码语言:javascript
运行
复制
15.15.119.103 - - [02/Sep/2016:13:54:03 +0300] "POST /api/meteo HTTP/1.1" 200 319 "-" "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0.2743.116 Safari/537.36"

但是当它来自阿迪诺的时候,它看起来很奇怪。

代码语言:javascript
运行
复制
15.15.119.103 - - [02/Sep/2016:13:53:54 +0300] "*HELLO*POST /api/meteo HTTP/1.1" 405 380 "-" "-"

因此,正如您所看到的,它出现在服务器上,不是像POST,而是像"_HELLO_POST“,它破坏了一切。问题是,我的代码中没有任何变化,而且它在一周内以某种方式工作。您可以在下面看到我的Arduino代码的平静:

代码语言:javascript
运行
复制
#include <WiFly.h>
#include "HTTPClient.h"

#define SSID      "bbbbbbb"
#define KEY       "ccccccc"

#define AUTH      WIFLY_AUTH_WPA2_PSK

#define HTTP_POST_URL "15.15.25.67/api/meteo"

SoftwareSerial uart(2, 3);
WiFly wifly(uart);
HTTPClient http;

String PostData;
char PostBuf[90];

        uart.begin(9600);
//      check if WiFly is associated with AP(SSID)
        if (!wifly.isAssociated(SSID)) {
          while (!wifly.join(SSID, KEY, AUTH)) {
            Serial.println("Failed to join " SSID);
            Serial.println("Wait 0.1 second and try again...");
            delay(100);
          }

          wifly.save();    // save configuration, 
        }  
        PostData.toCharArray(PostBuf, 90);
        while (http.post(HTTP_POST_URL, PostBuf, 10000) < 0) {
        }
        while (wifly.receive((uint8_t *)&get, 1, 1000) == 1) {
        Serial.print(get);
        }
        uart.end();

因此,它连接到WiFI和发送请求,但是请求的类型非常奇怪。我试着找出能帮上忙的钥匙,也许有人能给我建议?

如果需要的话,我把HTTPClient.h:

代码语言:javascript
运行
复制
#ifndef __HTTP_CLIENT_H__
#define __HTTP_CLIENT_H__

#define HTTP_CLIENT_DEFAULT_TIMEOUT         30000  // 3s

#define HTTP_MAX_HOST_LEN                   20
#define HTTP_MAX_PATH_LEN                   64
#define HTTP_MAX_BUF_LEN                    100

#define HTTP_DEFAULT_PORT                   80

#include <Arduino.h>
#include <WiFly.h>

class HTTPClient {
  public:
    HTTPClient();

    int get(const char *url, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
    int get(const char *url, const char *header, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
    int post(const char *url, const char *data, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
    int post(const char *url, const char *headers, const char *data, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);

  private:
    int parseURL(const char *url, char *host, int max_host_len, uint16_t *port, char *path, int max_path_len);
    int connect(const char *url, const char *method, const char *data, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);
    int connect(const char *url, const char *method, const char *header, const char *data, int timeout = HTTP_CLIENT_DEFAULT_TIMEOUT);

    WiFly* wifly;
};

#endif // __HTTP_CLIENT_H__

至于HTTPClient.cpp,如下所示:

代码语言:javascript
运行
复制
#include <string.h>
#include "HTTPClient.h"
#include "Debug.h"

HTTPClient::HTTPClient()
{
  wifly = WiFly::getInstance();
}

int HTTPClient::get(const char *url, int timeout)
{
  return connect(url, "GET", NULL, NULL, timeout);
}

int HTTPClient::get(const char *url, const char *headers, int timeout)
{
  return connect(url, "GET", headers, NULL, timeout);
}

int HTTPClient::post(const char *url, const char *data, int timeout)
{
  return connect(url, "POST", NULL, data, timeout);
}

int HTTPClient::post(const char *url, const char *headers, const char *data, int timeout)
{
  return connect(url, "POST", headers, data, timeout);
}

int HTTPClient::connect(const char *url, const char *method, const char *data, int timeout)
{
  return connect(url, method, NULL, data, timeout);
}

int HTTPClient::connect(const char *url, const char *method, const char *headers, const char *data, int timeout)
{
  char host[HTTP_MAX_HOST_LEN];
  uint16_t port;
  char path[HTTP_MAX_PATH_LEN];

  if (parseURL(url, host, sizeof(host), &port, path, sizeof(path)) != 0) {
    DBG("Failed to parse URL.\r\n");
    return -1;
  }

  if (!wifly->connect(host, port, timeout)) {
    DBG("Failed to connect.\r\n");
    return -2;
  }

  // Send request
  char buf[HTTP_MAX_BUF_LEN];
  snprintf(buf, sizeof(buf), "%s %s HTTP/1.1\r\n", method, path);
  wifly->send(buf);

  // Send all headers
  snprintf(buf, sizeof(buf), "Host: %s\r\nConnection: close\r\n", host);
  wifly->send(buf);

  if (data != NULL) {
    snprintf(buf, sizeof(buf), "Content-Length: %d\r\nContent-Type: text/plain\r\n", strlen(data));
    wifly->send(buf);
  }

  if (headers != NULL) {
    wifly->send(headers);
  }

  // Close headers
  wifly->send("\r\n");

  // Send body
  if (data != NULL) {
    wifly->send(data);
  }

  return 0;
}

int HTTPClient::parseURL(const char *url, char *host, int max_host_len, uint16_t *port, char *path, int max_path_len)
{
  char *scheme_ptr = (char *)url;
  char *host_ptr = (char *)strstr(url, "://");
  if (host_ptr != NULL) {
    if (strncmp(scheme_ptr, "http://", 7)) {
      DBG("Bad scheme\r\n");
      return -1;
    }
    host_ptr += 3;
  } else {
    host_ptr = (char *)url;
  }

  int host_len = 0;
  char *port_ptr = strchr(host_ptr, ':');
  if (port_ptr != NULL) {
    host_len = port_ptr - host_ptr;
    port_ptr++;
    if (sscanf(port_ptr, "%hu", port) != 1) {
      DBG("Could not find port.\r\n");
      return -3;
    }
  } else {
    *port = HTTP_DEFAULT_PORT;
  }

  char *path_ptr = strchr(host_ptr, '/');
  if (host_len == 0) {
    host_len = path_ptr - host_ptr;
  }

  if (max_host_len < (host_len + 1)) {
    DBG("Host buffer is too small.\r\n");
    return -4;
  }
  memcpy(host, host_ptr, host_len);
  host[host_len] = '\0';

  int path_len;
  char *fragment_ptr = strchr(host_ptr, '#');
  if (fragment_ptr != NULL) {
    path_len = fragment_ptr - path_ptr;
  } else {
    path_len = strlen(path_ptr);
  }

  if (max_path_len < (path_len + 1)) {
    DBG("Path buffer is too small.\r\n");
    return -5;
  }
  memcpy(path, path_ptr, path_len);
  path[path_len] = '\0';

  return 0;
}
EN

回答 1

Stack Overflow用户

发布于 2016-09-03 08:12:18

我发现了问题的根源,默认情况下,TCP连接打开时,WiFiShield v.1.0会说"HELLO“。事实上,它被写进了手册的深处。

我的连接不是那么快,所以在连接之前它可以说"HELLO“,但是我升级了路由器固件,它开始工作得更快,这就是为什么"HELLO”连接到下一个请求,在这个例子中是POST。解决方案很简单,只需添加:

代码语言:javascript
运行
复制
wifly.sendCommand("set comm remote 0\r");

此命令禁用WiFiShield上的欢迎消息。希望它能帮到别人。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/39294609

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档