ntruchsess / arduino_uip

UIPEthernet: A plugin-replacement of the stock Arduino Ethernet library for ENC28J60 shields and breakout boards. Full support for persistent (streaming) TCP-connections and UDP (Client and Server each), ARP, ICMP, DHCP and DNS. Build around Adam Dunkels uIP Stack. Further developed version can be found on https://github.com/UIPEthernet/UIPEthernet
490 stars 212 forks source link

client.connect() won't return if cable is removed #57

Closed adyn closed 10 years ago

adyn commented 10 years ago

Great library but unfortunately I hit some issues.

One of them (the easiest to reproduce) is this:

I have a client that sens http requests every few seconds to a server. If I remove the ethernet cable the program won't return from client.connect() function (even after I plug it back in). Here it is the sketch I use (with an Arduino Nano).

--------------------------------------------- Sketch

include <UIPEthernet.h>

EthernetClient client;

int cntSuccess = 0; int cntFailure = 0; int retry = 0; uint8_t mac[6] = {0x00,0x01,0x02,0x03,0x04,0x05};

void setup() {

Serial.begin(9600); Serial.println("Start..."); resetEthernet(); }

void resetEthernet() { Ethernet.begin(mac);

Serial.print("localIP: "); Serial.println(Ethernet.localIP()); Serial.print("subnetMask: "); Serial.println(Ethernet.subnetMask()); Serial.print("gatewayIP: "); Serial.println(Ethernet.gatewayIP()); Serial.print("dnsServerIP: "); Serial.println(Ethernet.dnsServerIP()); }

void loop() {

// --- SEND REQUEST ------------------------------------------------------------------------------ if (client.connect(IPAddress(157,166,226,26), 80)) { Serial.print("connected "); Serial.println(cntSuccess++);

retry = 0;

// Submit HTTP request:
client.println("GET /?hpt=sitenav HTTP/1.1");

client.println("Host: www.cnn.com");
client.println("User-Agent: arduino-ethernet");
client.println("Connection: close");
client.println();
client.flush();
client.stop();
delay(3000);

} else { Serial.print("connection failed "); Serial.println(cntFailure++); retry ++; if(retry == 3) { resetEthernet(); retry = 0; } delay(1000); } }

---------------------- Output Start... localIP: 192.168.1.118 subnetMask: 255.255.255.0 gatewayIP: 192.168.1.1 dnsServerIP: 208.122.23.22 connected 0 connected 1 connected 2


At this point I removed the cable and I plugged it back after a few seconds and nothing happened forward.

ntruchsess commented 10 years ago

The regular (blocking) connect() will wait until the tcp-timeouts have expired (which is several minutes...) before it recovers. If the initial SYN-packet happens to never reach the remote-host plugging back might not help immediatly in this case as the retransmits will take more and more time. I have no plans to change that. But you may want to check out the nonblocking connect() that is to be found in the 'ext-branch' https://github.com/ntruchsess/arduino_uip/tree/ext/examples/NonBlockingTcpClient

ntruchsess commented 10 years ago

I added the option to configure a connect-timeout that is independent of uIP internal timeouts: https://github.com/ntruchsess/arduino_uip/commit/5155710ea05a8c542d7588c9f01c1351334df5fd

configure by setting UIP_CONNECT_TIMEOUT in https://github.com/ntruchsess/arduino_uip/blob/master/utility/uipethernet-conf.h#L19.

ntruchsess commented 10 years ago

closing this as fixed. If the change doesn't suit your needs or you run into further issues reopen or create a new issue - whatever is more appropriate.