While loop 在循环内部分配的全局变量在循环外部不可用
我正在使用ESP8266无线芯片调用api。我声明了一个全局变量来分配服务器发送给它的令牌。变量赋值是在while循环中进行的。在这个循环中,我读取应答“thetoken”的内容并将其保存在全局变量中。 但是当我打印出while循环外的结果时,变量为空。但在循环内部,情况并非如此While loop 在循环内部分配的全局变量在循环外部不可用,while-loop,scope,arduino,esp8266,While Loop,Scope,Arduino,Esp8266,我正在使用ESP8266无线芯片调用api。我声明了一个全局变量来分配服务器发送给它的令牌。变量赋值是在while循环中进行的。在这个循环中,我读取应答“thetoken”的内容并将其保存在全局变量中。 但是当我打印出while循环外的结果时,变量为空。但在循环内部,情况并非如此 String deviceToken; WiFiClient client; if (!client.connect(hostIp, 80)){ Serial.println("Connection t
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十六进制-这是a),然后可以读取并存储所需的令牌。否则,您的令牌将是最后一个0
,或它后面的换行符
还要记住,不能保证回复总是被分块的(在这种情况下,这其实很奇怪),你也应该为“正常”回复做好准备
解决此问题的一个简单方法是发送
HTTP/1.0
请求,而不是HTTP/1.1
(只要服务器支持)。由于HTTP/1.0
不支持/允许分块传输,因此您的回复中将始终有一个“干净的”deviceToken
。感谢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是的,似乎这就是我删除令牌打印时的问题,它删除了它后面的“0”。这就是我等待的答案。谢谢。我现在尝试使用'\n'。并删除了循环外部的写EPROM。我认为它是这样运作的。令牌添加到下一个url字符串中,以进行新的api调用。但不幸的是,我收到了400个错误的请求。我在《邮递员》中测试了序列号上打印的url,它工作正常。@KeghamK。您的令牌现在可能有一个尾随的\r
,这可能会导致错误的请求。@KeghamK。使用HTTP/1.0
可能会更好/更容易-请参阅更新的答案。感谢HTTP/1.0部分,我将与服务器开发人员联系,看看他的服务器是否支持1。0@KeghamK. 通过将代码中的HTTP/1.1
更改为HTTP/1.0
,可以快速检查这一点。几乎所有的服务器都应该支持这一点。