全局变量内部while循环在循环外不可用
我打电话给一个使用ESP8266 WiFi芯片的api。 Im声明一个全局变量来分配服务器向它发送的令牌。变量赋值是在while循环内进行的。在这个循环中,我正在读取“令牌”回复的内容并将其保存在全局变量中。 但是,当我打印出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
在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
。
这就是我正在等待的答案。 Thankss。我现在想要做的是使用'\ n'。并且在循环外部删除了writeToEEPROM。我认为它是这样工作的。令牌被添加到下一个url字符串中以创建新的API调用。但不幸的是,我收到400个不好的请求。我在邮递员的串行测试打印的网址,它工作正常。 –
@KeghamK。您的令牌现在可能有一个尾随的'\ r',这可能导致错误的请求。 –
@KeghamK。使用HTTP/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;
}
你确定在上一次迭代中deviceToken是非空的吗?你能否有效地在最后调用'Serial.print(“”)'一次或多次,导致这个问题? – Phylogenesis
@Phylogenesis是似乎这是问题,当我删除令牌打印它删除后的“0”。 –