我有以下代码:
if (net.connect(host, port)) {
String req = "GET /curTemp?temp=" + String(temperatureFahrenheit) + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Authorization: Basic xxxxxxxxxxxxxxxxx\r\n" +
"Connection: close\r\n\r\n";
net.print(req);
// Get headers
while (net.connected()) {
String line = net.readStringUntil('\r');
if (line == "\r") {
break;
}
}
// Get temperature
StaticJsonBuffer<50> jsonBuffer;
JsonObject& root = jsonBuffer.parseObject(net.readStringUntil('\r'));
const char* temp = root["temp"];
Serial.print("Temp:");
Serial.println(temp);
} else {
Serial.println("connection failed");
}
这需要15秒才能完成,我不知道为什么。我可以在网络浏览器中使用相同的请求,它会立即返回。具体来说,net.readStringUntil似乎需要时间。
更新:我通过设置setTimeout(1000)找到了一种解决方法,但我不明白为什么这是必要的。请求是否应该关闭连接并且readStringUntil()在完成时终止?也许我不了解WiFiClientSecure?
UPDATE2:我发现了问题。见下面的答案。
答案 0 :(得分:0)
好的,我正在澄清这一点。每个例子都显示了&#39; \ r&#39;对于readStringUntil(),这可能会令人困惑。那么如果您使用&#39; \ r&#39;然后下一次阅读将以&#39; \ n&#39;开头。因此,如果您正在寻找标题的结尾,它实际上将是&#39; \ n \ r \ n&#39;因为从先前读取的行继续进行。那么你的数据与crlfs不同步会发生什么。我发现使用&#39; \ n&#39;对于终结器工作得更好,因为标头的标准格式以&#39; \ r \ n&#39;结尾。然后,您可以通过查找&#39; \ r&#39;来测试标题的结尾。 (\ n终止符被readStringUntil()吃掉)。然后,您可以启动另一个循环来获取数据。然后一切正常,不需要setTimeout。
示例:
if (net.connect(host, port)) {
String req = "GET /curTemp?temp=" + String(temperatureFahrenheit) + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Authorization: Basic dXNlcjpkYWYxMjM0\r\n" +
"Connection: close\r\n\r\n";
net.print(req);
delay(1000);
// Get headers
while (net.available()) {
// Note \n for terminator
String line = net.readStringUntil('\n');
// Only \r because \n is eaten by readStringUntil()
if (line == "\r") {
break;
}
}
// Now look for data (in my case only one line of JSON)
// No \r\n on this one.
String line = net.readStringUntil('}');
// Put back the character eaten by readStringUntil()
line = line + "}";
Serial.println(line);