获取 [e][wifigeneric.cpp:739] hostbyname(): dns 在执行 POST 请求时失败
Getting [e][wifigeneric.cpp:739] hostbyname(): dns failed when performing POST request
我正在开始电子和微控制器编程。
我制作了一个简单的电路,使用 DHT22 传感器测量温度和湿度。我还在 Node 和 Express 中创建了自己的 API(MongoDB 作为数据库)。它非常简单 API,只有两个端点:一个用于获取。一个用于 posting 数据。我可以使用 Postman(以及浏览器)创建成功的请求。
明确一点,我想将温度和湿度发送到我的 API,然后在 Vue 网站上使用这些数据做一些工作(我认为这根本不相关,但同样,只是为了清楚我想要实现的目标)。
下面说说我用的是什么:
Windows 10 OS
NodeMCU ESP32 微控制器
DHT22传感器
HTTPClient 库(我认为这是一个问题)
带有 Arduino.h 头文件的 PlatformIO
一切正常,但是当我尝试将数据发送到我的数据库时失败了。我总是收到以下错误
[e][wifigeneric.cpp:739] hostbyname(): dns 失败
我尝试使用 http://localhost:3000/endpoint 和 http://127.0.0.1/endpoint 发出 POST 请求(那部分真的很奇怪,为什么我在使用没有域名的 IP 地址?)。
我已经在网上查找了解决方案。我在 github 上遇到过许多类似的问题,但其中任何一个都对我有用)。此外,none 正在解决由第 739 行引起的错误。
在这里我将留下我的代码。这是简单而简短的,所以我将 post 全部。请不要因为我的 C++ 技能而责备我,我正在变得更好 :D
提前谢谢你,祝你今天或晚上愉快。
亲切的问候,Bartek。
#include <Arduino.h>
#include <DHT.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#define DHTPIN 22
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const char ssid[] = "MY_SSIID";
const char password[] = "MY_WIFI_PASSWORD";
const char apiAddress[] = "http://localhost:3000/reading";
unsigned long lastTime = 0;
unsigned long timerDelay = 60000;
struct sensorReading {
float temperature;
float humidity;
float heatIndex;
};
sensorReading readDataFromSensor();
void sendData(sensorReading * reading);
void setup() {
Serial.begin(9600);
dht.begin();
WiFi.begin(ssid, password);
WiFi.config(IPAddress(192, 168, 1, 223), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0));
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print('.');
}
}
void loop() {
if (millis() > lastTime + timerDelay) {
sensorReading data;
sensorReading * p_data = NULL;
data = readDataFromSensor();
p_data = &data;
sendData(p_data);
}
}
sensorReading readDataFromSensor() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
float heatIndex = dht.computeHeatIndex(temperature, humidity, false);
if (isnan(temperature) || isnan(humidity)) {
return sensorReading {};
}
const sensorReading dataToReturn {temperature, humidity, heatIndex};
return dataToReturn;
}
void sendData(sensorReading * reading) {
using namespace std;
if(WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(apiAddress, 3000);
http.addHeader("Content-Type", "application/json");
DynamicJsonDocument doc(1024);
doc["temperature"] = reading->temperature;
doc["humidity"] = reading->humidity;
doc["heatIndex"] = reading->heatIndex;
String dataToSend;
serializeJson(doc, dataToSend);
int responseCode = http.POST(dataToSend);
Serial.println(responseCode);
http.end();
} else {
Serial.print("Ups...");
}
lastTime = millis();
}
您正在使用两个参数调用 http
上的 begin()
方法,这两个参数是主机名和端口号(以及可选的 URI/path)。您传递的不是主机名,而是完整的 URL,HTTP 客户端正试图将其解析为主机名。
http.begin()
的单参数形式确实采用了 URL。您调用的表单没有。
您可以通过 reading the source code 确认这一点,它允许 begin()
方法的这些声明:
bool begin(WiFiClient &client, String url);
bool begin(WiFiClient &client, String host, uint16_t port, String uri = "/", bool https = false);
#ifdef HTTPCLIENT_1_1_COMPATIBLE
bool begin(String url);
bool begin(String url, const char* CAcert);
bool begin(String host, uint16_t port, String uri = "/");
bool begin(String host, uint16_t port, String uri, const char* CAcert);
bool begin(String host, uint16_t port, String uri, const char* CAcert, const char* cli_cert, const char* cli_key);
#endif
这个问题的一个重要提示是您在 URL 和 http.begin()
.
的第二个参数中重复了端口号
相反,您的代码应该如下所示:
http.begin(apiAddress);
或
const char apiName[] = "localhost";
const unsigned apiPort = 3000;
const char apiPath[] = "reading";
...
http.begin(apiName, apiPort, apiPath);
However - 这也不起作用,因为 localhost
和 127.0.0.1
表示“自己”或“同一台计算机”。您需要提供您尝试访问的服务器的真实 IP 地址; localhost
和 127.0.0.1
仅当您 运行 软件在其上时才提及它。
我正在开始电子和微控制器编程。
我制作了一个简单的电路,使用 DHT22 传感器测量温度和湿度。我还在 Node 和 Express 中创建了自己的 API(MongoDB 作为数据库)。它非常简单 API,只有两个端点:一个用于获取。一个用于 posting 数据。我可以使用 Postman(以及浏览器)创建成功的请求。
明确一点,我想将温度和湿度发送到我的 API,然后在 Vue 网站上使用这些数据做一些工作(我认为这根本不相关,但同样,只是为了清楚我想要实现的目标)。
下面说说我用的是什么:
Windows 10 OS NodeMCU ESP32 微控制器 DHT22传感器 HTTPClient 库(我认为这是一个问题) 带有 Arduino.h 头文件的 PlatformIO 一切正常,但是当我尝试将数据发送到我的数据库时失败了。我总是收到以下错误
[e][wifigeneric.cpp:739] hostbyname(): dns 失败
我尝试使用 http://localhost:3000/endpoint 和 http://127.0.0.1/endpoint 发出 POST 请求(那部分真的很奇怪,为什么我在使用没有域名的 IP 地址?)。
我已经在网上查找了解决方案。我在 github 上遇到过许多类似的问题,但其中任何一个都对我有用)。此外,none 正在解决由第 739 行引起的错误。
在这里我将留下我的代码。这是简单而简短的,所以我将 post 全部。请不要因为我的 C++ 技能而责备我,我正在变得更好 :D
提前谢谢你,祝你今天或晚上愉快。
亲切的问候,Bartek。
#include <Arduino.h>
#include <DHT.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <ArduinoJson.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#define DHTPIN 22
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
const char ssid[] = "MY_SSIID";
const char password[] = "MY_WIFI_PASSWORD";
const char apiAddress[] = "http://localhost:3000/reading";
unsigned long lastTime = 0;
unsigned long timerDelay = 60000;
struct sensorReading {
float temperature;
float humidity;
float heatIndex;
};
sensorReading readDataFromSensor();
void sendData(sensorReading * reading);
void setup() {
Serial.begin(9600);
dht.begin();
WiFi.begin(ssid, password);
WiFi.config(IPAddress(192, 168, 1, 223), IPAddress(192, 168, 1, 1), IPAddress(255, 255, 255, 0));
while(WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print('.');
}
}
void loop() {
if (millis() > lastTime + timerDelay) {
sensorReading data;
sensorReading * p_data = NULL;
data = readDataFromSensor();
p_data = &data;
sendData(p_data);
}
}
sensorReading readDataFromSensor() {
float temperature = dht.readTemperature();
float humidity = dht.readHumidity();
float heatIndex = dht.computeHeatIndex(temperature, humidity, false);
if (isnan(temperature) || isnan(humidity)) {
return sensorReading {};
}
const sensorReading dataToReturn {temperature, humidity, heatIndex};
return dataToReturn;
}
void sendData(sensorReading * reading) {
using namespace std;
if(WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin(apiAddress, 3000);
http.addHeader("Content-Type", "application/json");
DynamicJsonDocument doc(1024);
doc["temperature"] = reading->temperature;
doc["humidity"] = reading->humidity;
doc["heatIndex"] = reading->heatIndex;
String dataToSend;
serializeJson(doc, dataToSend);
int responseCode = http.POST(dataToSend);
Serial.println(responseCode);
http.end();
} else {
Serial.print("Ups...");
}
lastTime = millis();
}
您正在使用两个参数调用 http
上的 begin()
方法,这两个参数是主机名和端口号(以及可选的 URI/path)。您传递的不是主机名,而是完整的 URL,HTTP 客户端正试图将其解析为主机名。
http.begin()
的单参数形式确实采用了 URL。您调用的表单没有。
您可以通过 reading the source code 确认这一点,它允许 begin()
方法的这些声明:
bool begin(WiFiClient &client, String url);
bool begin(WiFiClient &client, String host, uint16_t port, String uri = "/", bool https = false);
#ifdef HTTPCLIENT_1_1_COMPATIBLE
bool begin(String url);
bool begin(String url, const char* CAcert);
bool begin(String host, uint16_t port, String uri = "/");
bool begin(String host, uint16_t port, String uri, const char* CAcert);
bool begin(String host, uint16_t port, String uri, const char* CAcert, const char* cli_cert, const char* cli_key);
#endif
这个问题的一个重要提示是您在 URL 和 http.begin()
.
相反,您的代码应该如下所示:
http.begin(apiAddress);
或
const char apiName[] = "localhost";
const unsigned apiPort = 3000;
const char apiPath[] = "reading";
...
http.begin(apiName, apiPort, apiPath);
However - 这也不起作用,因为 localhost
和 127.0.0.1
表示“自己”或“同一台计算机”。您需要提供您尝试访问的服务器的真实 IP 地址; localhost
和 127.0.0.1
仅当您 运行 软件在其上时才提及它。