我使用ESP8266 WiFi芯片呼叫api。我声明一个全局变量来分配服务器发送给它的令牌。变量赋值在while循环中进行。在这个循环中,我正在阅读回复的内容"令牌"并将其保存在全局变量中。 但是当我打印出while循环之外的结果变量为空时。但是在循环内部却不是。
String deviceToken;
WiFiClient client;
if (!client.connect(hostIp, 80)){
Serial.println("Connection to server failed.");
Serial.print(client.connect(hostIp, 80));
return;
}
String authURL = "/api/";
authURL += "startauth/";
authURL += serialValue;
Serial.print("Requesting URL: ");
Serial.println(authURL);
// This will send auth request to the server
client.print(String("GET ") + authURL + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timeout = millis();
while (client.available() == 0) {
if (millis() - timeout > 5000) {
Serial.println(">>> Client Timeout !");
client.stop();
return;
}
}
// Read Auth reply from server and print them to Serial
while(client.available()){
String token = client.readStringUntil('\r');
deviceToken = token;
writeDeviceToken(token.c_str()); //Function to write data in eeprom
Serial.print(deviceToken); //NOT EMPTY
}
Serial.print("Device Token:" + deviceToken); //EMPTY VARIABLE
答案 0 :(得分:2)
在while循环中,您逐行循环遍历HTTP标头和数据,并每次覆盖deviceToken
。这没关系,除了每一行都以\r\n
结尾,而不仅仅是\r
- (另外,你可能只想将令牌写入eeprom,而不是每个标题)。
因此,读取的最后一个令牌是单个\n
,然后将其放入deviceToken
。您需要在每行之后读取额外的字节。
另一种方法是阅读,直至到达\r\n\r\n
(标题栏结束),然后读取大小(28个十六进制 - 这是一个chunked transfer),然后你就可以阅读和存储你想要的令牌。否则,您的令牌将是最后0
或后续的换行符。
另请注意,无法保证回复总是会被分块(在这种情况下实际上相当奇怪),您也应该为“正常”回复做好准备。
解决此问题的一种简单方法是发送HTTP/1.0
请求而不是HTTP/1.1
(只要该服务器支持它)。由于HTTP/1.0
不支持/允许分块转移,因此您在回复中始终会有一个“干净”deviceToken
。
答案 1 :(得分:0)
感谢Danny_ds的指示,我能够解决我的问题,并想到在这里分享工作代码作为参考。
// Read Auth reply from server and print them to Serial
while(client.available()){
char c = client.read();
response += c;
}
String testStatus = response;
if((strstr(testStatus.c_str(),"HTTP/1.1 500")) != NULL) {
Serial.println("Found reponse 500");
return;
} else if ((strstr(testStatus.c_str(),"HTTP/1.1 200")) != NULL) {
Serial.println("Found reponse 200");
//Grabing the token after the header
String token = response.substring(response.indexOf("\r\n\r\n") + 8 );
//Removing the \r in end of token
token.remove(40);
deviceToken = token;
writeDeviceToken(deviceToken.c_str());
delay(500);
Serial.print("Device Token:" + deviceToken);
return;
}