2011-09-15 72 views
5

我正在使用具有以太網屏蔽的Arduino Uno。許多客戶端打印後Arduino(Uno)以太網客戶端連接失敗

發送很多HTTP請求後,client.println(...),連接時客戶端開始失敗。失敗的時間似乎是隨機的,循環中的序列讀數可以在〜1000和〜7000之間任意變化。

的錯誤不是做與以太網發送緩衝區溢出(以下this advice

這裏是一個錯誤的代碼:

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

// Network constants 
byte mac[] = {0x00, 0x23, 0xdf, 0x82, 0xd4, 0x01}; 
byte ip[] = {/*REDACTED*/}; 
byte server[] = {/*REDACTED*/}; 
int port = /*REDACTED*/; 
Client client(server, port); 

// State 
int sequence; 

void setup(){ 
    Ethernet.begin(mac, ip); 
    Serial.begin(9600); 
    sequence = 0; 

    delay(1000); 
} 

void loop(){ 
    httpPut("/topic/:test/publish?sessionId=SESenanhygrp"); 
    Serial.println(sequence++); 
} 

void httpPut(char* url){ 
    if (!client.connect()) { 
     Serial.println("EXCEPTION: during HTTP PUT. Could not connect"); 
     return; 
    } 

    client.print("PUT"); 
    client.print(" "); 
    client.print(url); 
    client.println(" HTTP/1.0"); 
    client.println(); 

    while(!client.available()){ 
     delay(1); 
    } 

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

    while(client.connected()){ 
     Serial.println("Waiting for server to disconnect"); 
    } 

    client.stop(); 
} 

在以下段將出現錯誤

if (!client.connect()) { 
    Serial.println("EXCEPTION: during HTTP PUT. Could not connect"); 
    return; 
} 
+0

在客戶端連接失敗的時候,我會做兩件事:(1)檢查服務器日誌中是否有任何證據服務器接收失敗的連接請求; (2)在服務器上使用'netstat'來確定之前的連接是否已經關閉或者正在等待。 – NPE

+0

除上述之外,3)我會檢查堆棧是否溢出。 4)數千個週期後是否發生內存泄漏。 – Jeff

+0

服務器日誌沒有顯示任何問題。使用Arduinos時內存始終是一個問題,但上面的代碼應該是'內存安全' – ChrisSSocha

回答

0

v22中的Arduino以太網庫存在一個錯誤(如Linux/Windows V0022/1.0 Ethernet problem SOLVED中所述)。

我的解決方案是使用Ethernet2庫(來自tinker.it的Peter)。代碼需要小修補,但現在一切似乎都工作正常。我已經成功地發送了超過40000多封沒有任何問題的HTTP消息。 (偶爾單個消息不能發送,但是這個錯誤率低於4%)

0

我會通過在消息之間增加10倍的時間來降低通信速率。那麼如果你在1000到7000條消息之間沒有得到一個錯誤,這可能意味着你說的太快而不是你的小Arduino,並且它的緩衝區會導致溢出,通信庫不幸地無法恢復。在每條消息之後,我還會通過串行端口監視緩衝區中的Arduino空閒字節。你也可以通過發送消息來儘可能快地從PC上測試這種行爲,看看這會在一段時間後凍結你的Arduino。如果是這樣,您可能會考慮拒絕消息,直到緩衝區超過某個限制。