我正在尝试在微控制器 ESP32 上创建服务器和客户端交互。它将由简单的 HTTP 服务器和客户端组成。所以客户端会向服务器发送一个POST请求,服务器会根据收到的数据做一些逻辑处理。 对于更多上下文,这里是服务器端代码:
if (client.available()) { // if there's bytes to read from the client,
char c = client.read(); // read a byte, then
Serial.write(c); // print it out the serial monitor
header += c;
if (c == '\n') { // if the byte is a newline character
// if the current line is blank, you got two newline characters in a row.
// that's the end of the client HTTP request, so send a response:
if (currentLine.length() == 0) {
int contentLength = header.indexOf("Content-Length: ");
if (contentLength != -1) {
contentLength = header.substring(contentLength + 16).toInt();
int bodyRead = 0;
while (bodyRead < contentLength && client.available()) {
char c = client.read();
requestBody += c;
bodyRead++;
}
}
// Separate direction and vehicle id
int sd = requestBody.indexOf('=');
int vd = requestBody.indexOf('&');
String direction = requestBody.substring(sd + 1, vd);
int pos = requestBody.indexOf('=', vd);
String vehicle = requestBody.substring(pos + 1);
// HTTP headers always start with a response code (e.g. HTTP/1.1 200 OK)
// and a content-type so the client knows what's coming, then a blank line:
client.println("HTTP/1.1 200 OK");
client.println("Content-type:text/html");
client.println("Connection: close");
client.println("Got it, " + direction + " for : " + vehicle);
client.println();
Serial.println("Request Body : " + requestBody);
Serial.println("Direction : " + direction);
Serial.println("Vehicle : " + vehicle);
// Break out of the while loop
break;
} else { // if you got a newline, then clear currentLine
currentLine = "";
}
} else if (c != '\r') { // if you got anything else but a carriage return character,
currentLine += c; // add it to the end of the currentLine
}
}
这是客户端代码:
if(WiFi.status()== WL_CONNECTED){
WiFiClient client;
HTTPClient http;
// Your Domain name with URL path or IP address with path
http.begin(client, serverName);
// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
// Data to send with HTTP POST
String httpRequestData = "from=south&id=military";
// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);
Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);
// Free resources
http.end();
}
else {
Serial.println("WiFi Disconnected");
}
现在的问题是服务器无法正确读取POST请求。 在测试客户端之前,我使用 API Tester(移动应用程序)来测试服务器,它按预期工作。所以我的服务器在串行监视器中打印出这些:
POST / HTTP/1.1
user-agent: apitester.org Android/7.5(641)
accept: */*
Content-Type: application/x-www-form-urlencoded
Content-Length: 22
Host: 192.168.4.1
Connection: Keep-Alive
Accept-Encoding: gzip
Request Body : from=south&id=military
Direction : south
Vehicle : military
Client disconnected.
但是当我从客户端发送 POST 请求时,我的服务器不会在串行监视器上返回任何数据
POST / HTTP/1.1
Host: 192.168.4.1
User-Agent: ESP32HTTPClient
Connection: keep-alive
Accept-Encoding: identity;q=1,chunked;q=0.1,*;q=0
Content-Type: application/x-www-form-urlencoded
Content-Length: 23
Request Body :
Direction :
Vehicle :
Client disconnected.
我还没弄清楚为什么会发生这种情况。我猜错误是在客户端?因为服务器在与 API Tester 一起使用时才能工作。但从我阅读的许多教程来看,我的客户端代码应该可以正常工作。
另外因为没有错误代码之类的东西,我不知道应该从哪里解决这个问题。我希望你能帮我解决这个问题。
仅此而已,欢迎任何反馈,谢谢
当您从
Content-Length
中提取 header
值时,您期望 Content-Length
是存储在 header
中的最后一行,但在您的示例中显然不是这种情况。
您需要找到整数值后面的
'\r'
字符(因为您没有将 '\n'
字符添加到 header
),然后仅提取 "Content-Length: "
和 '\r'
之间的行部分。您当前正在提取从 "Content-Length: "
到 header
末尾的所有内容。