Timeout delay in sendUDP in endPacket when target is not online

Status
Not open for further replies.

ReflectedLight

New member
If I send a UDP packet to a device that is not online, there is an approximately 1.6 second timeout delay. This appears to be 8 retries with 200ms timeouts. This is happening in sendUDP() called from endPacket(). Since UDP is a connectionless protocol, I imagine it should be "Fire & Forget" and there shouldn't be a penalty for sending a packet to non-existent device. Even waiting around for a success result seems odd.

I am trying to send 8 bytes with UDP every 10ms to 6 devices on a local area network. Occasionally one or more of those devices will be absent from the net. Any delay or blocking with throw off my data distribution... I am working with teensy 3.2 & the Wiz820io/SD card combo.

Btw. Is there anyway to do UDP multicast on the W5200 in Teensyduino?

In the following example, change IPAddress "target" & "ip" to suit. Then take "target" offline.

Code:
#include <Ethernet.h>
#include <SPI.h>
#include <EthernetUdp.h>
#include <T3Mac.h>  // where we get our mac address from

IPAddress target(192, 168, 2, 1); // 
IPAddress ip(192, 168, 2, 7);

EthernetUDP UdpReflect;
unsigned int localReflectPort = 8888;

long udpThenA, udpNowA;
long udpThenB, udpNowB;
long udpThenC, udpNowC;

char reflectorBuffer[8];

void setup() {
  
  Serial.begin(57600);
  delay(2000);
  Serial.println("Reading MAC from hardware...");
  read_mac();

  Serial.print("MAC: ");
  print_mac();
  Serial.println();

  Ethernet.begin(mac, ip);
  UdpReflect.begin(localReflectPort);
}

void loop() {
  Serial.print("Sent:");
  udpThenA = millis();
  UdpReflect.beginPacket(target, localReflectPort);
  udpNowA = millis();

  udpThenB = millis();
  UdpReflect.write(reflectorBuffer, 8);
  udpNowB = millis();

  udpThenC = millis();
  UdpReflect.endPacket();
  udpNowC = millis();

  Serial.print("beginPacket ");
  Serial.print(udpNowA - udpThenA);
  Serial.print(" ms : write ");
  Serial.print(udpNowA - udpThenA);
  Serial.print(" ms : endPacket ");
  Serial.println(udpNowC - udpThenC);
}

My output when target is absent:
Reading MAC from hardware...
MAC: 04:E9:E5:01:9E:EA
Sent:beginPacket 0 ms : write 0 ms : endPacket 1602
Sent:beginPacket 0 ms : write 0 ms : endPacket 1602
Sent:beginPacket 0 ms : write 0 ms : endPacket 1602
....


My output when target is present:
Reading MAC from hardware...
MAC: 04:E9:E5:01:9E:EA
Sent:beginPacket 0 ms : write 0 ms : endPacket 1602
Sent:beginPacket 0 ms : write 0 ms : endPacket 0
Sent:beginPacket 0 ms : write 0 ms : endPacket 0
Sent:beginPacket 0 ms : write 0 ms : endPacket 0
.....

Thanks for your attention!
 
The only UDP "pseudo-connection" I've seen is in MS Windows.

In any system, there can be an ARP failure. WIth the destination in the same LAN, the NICs and switches have to do ARP (MAC address to IP address relationship). So the receiving side needs to announce via ARP before UDP or TCP or any IP can work.

I've used lots of UDP on Wiznet products, with the destination turned off, and not have any impact to the sender. As it should be. But I didn't use the library you are using (I did all my own code, some 3 years ago, with the 5100 chip.)
I don't know what UdpReflect.begin() does. Implicit that a method in that same class acts like ICMP echo but uses UDP? The UDP socket listener would have to have be designed to echo the packet if it came on a certain port number?

UDP multicast within a subnet - by definition has to work else DHCP and other such can't work.
UDP multicast to the WAN - well, unlikely.

a nit: your "long" types would be more correct as unsigned long a.k.a. uint32_t in stdint.h
 
Last edited:
The only UDP "pseudo-connection" I've seen is in MS Windows.

In any system, there can be an ARP failure. WIth the destination in the same LAN, the NICs and switches have to do ARP (MAC address to IP address relationship). So the receiving side needs to announce via ARP before UDP or TCP or any IP can work.

I've used lots of UDP on Wiznet products, with the destination turned off, and not have any impact to the sender. As it should be. But I didn't use the library you are using (I did all my own code, some 3 years ago, with the 5100 chip.)
I don't know what UdpReflect.begin() does. Implicit that a method in that same class acts like ICMP echo but uses UDP? The UDP socket listener would have to have be designed to echo the packet if it came on a certain port number?

UDP multicast within a subnet - by definition has to work else DHCP and other such can't work.
UDP multicast to the WAN - well, unlikely.

a nit: your "long" types would be more correct as unsigned long a.k.a. uint32_t in stdint.h


I'm not sure what you mean by "pseudo-connection" or why you mention it.

The ARP failure is not an issue I am concerned with here. As I demonstrated in code, when the target is online there is no penalty to the sender.

UdpReflect is just a variable name that "reflects" its use as a relay in the original code, from which this was extracted.

The Functionality of all parts of this code are covered in the standard EthernetUdp class library as documented on the Arduino site.

The library I am using is the standard Ethernet library from teensyduino, which seems appropriate for this forum.
From the Compiler:
"Using library Ethernet in folder: /Applications/Arduino.app/Contents/Java/hardware/teensy/avr/libraries/Ethernet (1.0.x format)"
Teensyduino 1.25-beta2


a nit back atcha: saying something is possible, without explaining how or providing code.
 
Can you post the exact T3Mac code, or a link to it if you're using a library without any modifications?

I can't run this without that missing piece.
 
Hi !

I have the same problem like ReflectedLight : when the target of the UDP packet is not online, the program still waiting ....

Thanks for all,

Hugo
 
recover an old post.
I'm also sending out UDP messages quite fast and if the destination address is off / wrong IP teensy starts to be "super slow" between one message and the other, causing huge delay that I can't have.

Of course, in the standard situation when the destination is available I have no issue at all, but I would like to be able to at least handle this situation with an error message instead of making my teensy un-usable because of delays.

Any suggestions?
 
Quick followup to this old thread. I've created an issue on github to track this problem.

https://github.com/PaulStoffregen/Ethernet/issues/25

The ARP failure is not an issue I am concerned with here. As I demonstrated in code, when the target is online there is no penalty to the sender.

This probably is indeed ARP.

When the destination is online (on the same LAN), it answers the ARP query. Then the Wiznet chip knows the 6 byte mac address, which it needs to send the packet since the destination is on the same LAN. If the destination isn't on the same LAN (subnet) then it can send to the gateway address, which presumably has answered ARP previously.

Reading the datasheet, I don't see any way we can know whether ARP has worked previously.

There is a SEND_MAC command documented for the Sn_CR register. But it requires writing the 6 byte destination mac address.

I don't see any solution, but created the github issue...
 
You can turn off the retries using this command: W5100.setRetransmissionCount(0);
or you can lower the retry time with this: W5100.setRetransmissionTime(10);

I've successfully used the 0 retry option on a few projects where the receiving teensies aren't always online.
 
I've added these functions to the main Ethernet class, so you won't need to include w5100.h (which isn't meant to be used by Arduino programs) and so they're protected by SPI transactions.
 
I've been struggling this issue for some time. Have there been any improvement yet? There still some delay when using `Ethernet.setRetransmissionCount(0)`
 
Status
Not open for further replies.
Back
Top