1

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

我遇到的问题是我的 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 盾牌后,我就没有更新过它的固件,老实说,我无法告诉你它正在运行什么版本。但是,我觉得这完全是另外一回事,我就是不能指望它。

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

请不要对我的代码风格大打出手。这只是初稿。

4

1 回答 1

2

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

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

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

client.stop()

在最后一个 println() 之后。

您可以使用两个工具确认发生了什么: - netstat(或类似工具)会告诉您服务器是否在 CLOSE_WAIT 或 TIME_WAIT 中累积连接 - Wireshark 会让您查看服务器是否正在尝试关闭连接并且未被确认阿杜诺。

于 2013-07-03T06:09:56.240 回答