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

时间:2016-12-29 13:35:18

标签: while-loop scope arduino esp8266

我使用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

enter image description here

2 个答案:

答案 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;
   }