【问题标题】:POST request on arduino with ESP8266 using WifiESP library使用 WifiESP 库在带有 ESP8266 的 arduino 上发布请求
【发布时间】:2017-05-12 07:12:13
【问题描述】:

我正在尝试使用 WifiESP 库 (https://github.com/bportaluri/WiFiEsp) 发出 RESTful POST 请求。我能够使用 curl 成功发出请求,但使用 Arduino 和 ESP 时始终会出错。我怀疑问题与库所需的 POST 请求的手动格式有关,但我没有发现任何问题。这是我清理过的代码:

if (client.connect(server, 80)) {
Serial.println("Connected to server");
// Make a HTTP request
String content = "{'JSON_key': 2.5}";   // some arbitrary JSON
client.println("POST /some/uri HTTP/1.1");
client.println("Host: http://things.ubidots.com");
client.println("Accept: */*");
client.println("Content-Length: " + sizeof(content));
client.println("Content-Type: application/json");
client.println();
client.println(content);
}

我得到的错误(通过串行监视器)是这样的:

Connected to server
[WiFiEsp] Data packet send error (2)
[WiFiEsp] Failed to write to socket 3
[WiFiEsp] Disconnecting 3

我成功的 curl 请求如下所示:

curl -X POST -H "Content-Type: application/json" -d 'Some JSON' http://things.ubidots.com/some/uri

【问题讨论】:

  • 几件事。我注意到,当您使用 println 函数时,库会同时附加 \r\n 而不仅仅是 \n。尝试手动执行\ns 并使用print 函数。如果这样做不行,请将整个内容打印到 Serial 并将其与 curl 帖子的wireshark 跟踪进行比较。
  • @leetibbett 感谢您的回复。 \r\n 最终不是问题,但它确实让我查看了 HTTP 协议文档,该文档帮助我发现了其他几个问题。

标签: rest arduino http-post esp8266


【解决方案1】:

经过一些实验,这里是多个问题的解决方案。

  1. JSON 对象的格式不正确。单引号不被接受,所以我需要转义双引号。
  2. 主机在 POST 请求中不需要“http://”; POST 是一种 HTTP 方法。
  3. sizeof() 方法返回内存中变量的大小(以字节为单位)而不是字符串的长度。它需要替换为 .length()。
  4. 将整数附加到字符串需要强制转换。

这是更正后的代码:

if (client.connect(server, 80)) {
  Serial.println("Connected to server");
  // Make the HTTP request
  int value = 2.5;  // an arbitrary value for testing
  String content = "{\"JSON_key\": " + String(value) + "}";
  client.println("POST /some/uri HTTP/1.1");
  client.println("Host: things.ubidots.com");
  client.println("Accept: */*");
  client.println("Content-Length: " + String(content.length()));
  client.println("Content-Type: application/json");
  client.println();
  client.println(content);
}

【讨论】:

    【解决方案2】:

    Troy D 解释的代码是正确的并且可以正常工作。我认为将数据发布到服务器的错误是由于这一行 client.println("Content-Length: " + sizeof(content)); 正确的方法是
    client.println("内容长度:" + String(content.length()));

    现在遇到这个错误 连接到服务器

     [WiFiEsp] Data packet send error (2)
     [WiFiEsp] Failed to write to socket 3
     [WiFiEsp] Disconnecting 3
    

    这是库的错误,你可以忽略它。

    【讨论】:

      【解决方案3】:

      据我所知,“数据包发送错误(2)”、“无法写入套接字 3”和“断开 3”的问题在 WifiEsp 库中不是问题,相信更有可能是在 AT 固件中。默认情况下,http 标头包含一个“连接:关闭”参数,在正常情况下应该是正确的。但是,由于此错误,服务器将在客户端收到回复之前断开连接,并且来自服务器的任何响应都将被识别为垃圾数据。使用值“Connection: keep-alive”作为解决方法可以以正确的方式从服务器接收接受。

      我正在针对我在我的一个服务器和控制器中创建的基于 MVC 的 Web Api 运行我的 Arduino + ESP8266-07 后置方法我使用单个字符串作为返回值,如果一切正常,我返回的值ok 只是 WifiEsp 跟踪的字符串之一(它仍然会在它返回的响应标头中包含 http 状态代码)

      public async Task<string> Post([FromBody]JObject payload)
      {
        //Code to handle the data received, in my case I log unit ip, macaddress, datetime and sensordata into a db with entity framework
        return "SEND OK";
      }
      

      所以在您的 Arduino 代码中尝试以下操作:

      String PostHeader = "POST http://" + server + ":" + String(port) + "/api/values HTTP/1.1\r\n";
      PostHeader += "Connection: keep-alive\r\n";
      PostHeader += "Content-Type: application/json; charset=utf-8\r\n";
      PostHeader += "Host: " + server + ":" + String(port) + "\r\n";
      PostHeader += "Content-Length: " + String(jsonString.length()) + "\r\n\r\n";
      PostHeader += jsonString;
      
      client.connect(server.c_str(), port);
      client.println(PostHeader);
      client.stop();
      

      在库源代码中的 debug.h 文件中,您可以更改定义并获得更多输出到串行控制台。打开文件并更改

      #define _ESPLOGLEVEL_ 3
      

      #define _ESPLOGLEVEL_ 4
      

      保存文件并将您的源代码重新编译/部署到您的 Arduino,您将获得有关库发送的所有 AT 命令以及库收到的返回内容的大量信息。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-01-27
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多