Arduino - 无客户端失败的延迟循环

时间:2013-07-01 02:41:57

标签: arduino

任何认为标题不正确或误导的人,请随时更新。

我遇到的问题是我的Uno R3和WiFi Shield。我现在真的无法分享确切的消息来源,但这可以很好地解释这个问题:

#include <WiFi.h>
#include <SPI.h>
#include <Ethernet.h>


char httpHost[] = "my.local.site.com";
IPAddress server(192,168,1,10);
int serverPort = 80;

char ssid[] = "myssid";
char password[] = "abcd123456";

int thingy = 0;

float lastTick = 0;
float tickInterval = 30000;

WiFiClient client;
boolean lastConnected = false;

void setup()
{
  Serial.begin(9600);
  connectWifi();
  pinMode(2, INPUT);
}

void loop()
{
  float currentMillis = millis();
  if (currentMillis >= (lastTick + tickInterval) || currentMillis < lastTick) {
    pollThingy();
    logUpdate();
    lastTick = currentMillis;
  }

  while (client.available()) {
    char c = client.read();
    Serial.print(c);
  }

  if (client.connected() == false && lastConnected == true) {
    Serial.println("-- Disconnected.");
    client.stop();
  }

  lastConnected = client.connected();

  if (lastConnected == true) {
    digitalWrite(13, HIGH);
  } else {
    digitalWrite(13, LOW);
  }
}

void connectWifi()
{
  int status = WL_IDLE_STATUS;

  if (WiFi.status() == WL_NO_SHIELD) {
    Serial.println("No WiFi Shield Found! Aborting!");
    while(true) { }
  }
  int i = 0;
  while(true) {
    Serial.print("Attempting to connect to network: ");
    Serial.print(ssid);
    Serial.print(" Attempt #");
    Serial.println(++i);

    status = WiFi.begin(ssid, password);

    if (status == WL_CONNECTED) break;

    delay(10000);
  }

  if (status == WL_CONNECTED) {
    Serial.println("Connected!");
  } else {
    Serial.println("Failed connecting! Aborting!");
    while(true) { }
  }
}

void pollThingy()
{
  thingy = digitalRead(2);
}

void logUpdate()
{ 
  Serial.println("Logging update: ");

  if (client.connected() == false) {
    Serial.print("-- Connecting to ");
    Serial.print(server);
    Serial.print(":");
    Serial.println(serverPort);

    if (client.connect(server, serverPort)) {
      Serial.println("     Connected!");
      client.print("GET /some/Uri/with/arguments?output=json HTTP/1.1");
      client.println(" HTTP/1.1");

      client.print("Host: ");
      client.println(httpHost);

      client.println("Connection: close");
      client.println();
    } else {
      Serial.println("      Connection failed!");
    }
  } else {
    Serial.println("-- Already connected... Skipping, this time...");
  }
}

现在我遇到的问题似乎有点疯狂。这将正常工作,并按预期每30秒记录一次给定端点的更新。但是,大约2个小时后它就会失速并且再也没有做任何事情了。我已经通过观察串行监视器来确认,该监视器除了最后一个预期的Serial.println()语句之外什么都不返回,但是没有错误显示或任何东西。

我没有更新WiFi盾牌上的固件,因为我得到了它,老实说,我无法告诉你它正在运行什么版本。但是,我觉得这完全是另一回事,我只是不能指责它。

有人可以提供任何建议吗?

请不要过分关注我的代码风格。这只是初稿。

1 个答案:

答案 0 :(得分:2)

您永远不会关闭您打开的连接。您显示与Web服务器的连接,但没有Keep-Alive标头。服务器不应该让人们坐在打开的连接上,以防万一有其他事务需要遵循。我希望服务器放弃连接。

Arduino代码永远不会关闭连接,它只是在每次看到服务器断开连接时都会打开另一个连接。在某些时候,网络堆栈用尽了手柄来跟踪碎片。

间隔30秒,没有理由尝试保持对Web服务器的连接。添加

client.stop()

在最后一个println()之后。

您可以使用两种工具确认发生了什么: - netstat(或类似)会告诉您服务器是否在CLOSE_WAIT或TIME_WAIT中累积连接 - Wireshark会让你看看服务器是否正在尝试关闭连接而Arduino没有确认。