我正在做基于Arduino Uno的小型气象站的工作。事实上,我已经创建了一个原型,可以测量CO2的湿度、温度、压力和水平,并将数据通过POST请求发送到服务器。整整一周,它以每小时的方式将数据完美地发送到服务器。但昨天我发现没有新的数据。我的第一个想法是WiFi出了点问题,我重新启动路由器,检查连接情况,一切都很完美。我认为如果Arduino出了什么问题并重新启动它,它就能工作。因此,我检查连接后得到了什么,并回答如下:
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中我发现了一些有趣的东西:
邮递员发来的工作邮件请求如下:
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"
但是当它来自阿迪诺的时候,它看起来很奇怪。
15.15.119.103 - - [02/Sep/2016:13:53:54 +0300] "*HELLO*POST /api/meteo HTTP/1.1" 405 380 "-" "-"
因此,正如您所看到的,它出现在服务器上,不是像POST,而是像"_HELLO_POST“,它破坏了一切。问题是,我的代码中没有任何变化,而且它在一周内以某种方式工作。您可以在下面看到我的Arduino代码的平静:
#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:
#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,如下所示:
#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;
}
发布于 2016-09-03 08:12:18
我发现了问题的根源,默认情况下,TCP连接打开时,WiFiShield v.1.0会说"HELLO“。事实上,它被写进了手册的深处。
我的连接不是那么快,所以在连接之前它可以说"HELLO“,但是我升级了路由器固件,它开始工作得更快,这就是为什么"HELLO”连接到下一个请求,在这个例子中是POST。解决方案很简单,只需添加:
wifly.sendCommand("set comm remote 0\r");
此命令禁用WiFiShield上的欢迎消息。希望它能帮到别人。
https://stackoverflow.com/questions/39294609
复制相似问题