c++ - 获取[e][wifigeneric.cpp :739] hostbyname(): dns failed when performing POST request

标签 c++ esp32 platformio arduino-esp32

我正在开始电子和微 Controller 编程。

我制作了一个简单的电路,使用 DHT22 传感器来测量温度和湿度。我还在 Node 和 Express 中制作了自己的 API(MongoDB 作为数据库)。这是一个非常简单的 API,只有两个端点:一个用于获取。一个用于发布数据。我可以使用 Postman(以及浏览器)创建成功的请求。

需要明确的是,我想将温度和湿度发送到我的 API,然后在 Vue 网站上对这些数据进行一些处理(我认为这根本不相关,但同样,只是为了清楚我的意思)我正在努力实现)。

现在我会说我正在使用什么:

Windows 10 操作系统 NodeMCU ESP32 微 Controller DHT22传感器 HTTPClient 库(我认为这个库引起了问题) PlatformIO 与 Arduino.h 头文件 一切都很好,但是当我尝试将数据发送到数据库时,事情失败了。我总是收到以下错误

[e][wifigeneric.cpp:739] hostbyname(): DNS 失败

我尝试使用 http://localhost:3000/endpoint 和 http://127.0.0.1/endpoint 发出 POST 请求(这部分真的很奇怪,为什么我在使用没有域名的 IP 地址时会出现 DNS 错误?)。

我已经在网上查找了解决方案。我在 github 上遇到了很多类似的问题,但其中任何一个都对我有用)。而且,他们都没有解决第 739 行引起的错误。

在这里我将留下我的代码。它很简单又简短,所以我将全部发布。请不要责怪我的 C++ 技能,我正在变得更好:D

预先感谢您,祝您度过愉快的一天或晚上。

亲切的问候,巴特克。

#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/路径) )。您不是传递主机名,而是传递完整的 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);

但是 - 这也不起作用,因为 localhost127.0.0.1 意味着“自己”或“同一台计算机”。您需要提供您尝试访问的服务器的真实 IP 地址; localhost127.0.0.1 仅当您在其上运行软件时才引用它。

关于c++ - 获取[e][wifigeneric.cpp :739] hostbyname(): dns failed when performing POST request,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68508224/

相关文章:

c++:段错误(核心转储)

c++ - Boost spirit编译问题

pypi - 无法使用upip在esp32上安装uasyncio包

arduino - ESP32 服务中断例程的速度有多快?

visual-studio-code - 从平台IO上传代码到esp32

visual-studio-code - 在vscode集成终端中手动运行 `platformio run -v`

c++: 'std::is_fundamental' 的替代方案?

c++ - 如何在 Resharper 中更改 doxygen 格式化样式?

C++ - 如何将回调绑定(bind)到类方法而不是静态的?