While loop 在循环内部分配的全局变量在循环外部不可用

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

我正在使用ESP8266无线芯片调用api。我声明了一个全局变量来分配服务器发送给它的令牌。变量赋值是在while循环中进行的。在这个循环中,我读取应答“thetoken”的内容并将其保存在全局变量中。 但是当我打印出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十六进制-这是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
,可以快速检查这一点。几乎所有的服务器都应该支持这一点。