Forum Rule: Always post complete source code & details to reproduce any issue!
Results 1 to 12 of 12

Thread: Timeout delay in sendUDP in endPacket when target is not online

  1. #1

    Timeout delay in sendUDP in endPacket when target is not online

    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!

  2. #2
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    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 by stevech; 10-05-2015 at 03:59 AM.

  3. #3
    Quote Originally Posted by stevech View Post
    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.

  4. #4
    Senior Member
    Join Date
    Jun 2013
    Location
    So. Calif
    Posts
    2,828
    well, that's nice.

  5. #5
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,171
    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.

  6. #6
    Quote Originally Posted by PaulStoffregen View Post
    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 Paul,

    It is available in article #14 in this thread:
    https://forum.pjrc.com/threads/91-te...ll=1#post48477

    Thanks

  7. #7
    Member
    Join Date
    Nov 2016
    Location
    France
    Posts
    30
    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

  8. #8
    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?

  9. #9
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,171
    Quick followup to this old thread. I've created an issue on github to track this problem.

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

    Quote Originally Posted by ReflectedLight View Post
    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...

  10. #10
    Junior Member
    Join Date
    Jul 2018
    Posts
    2
    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.

  11. #11
    Senior Member PaulStoffregen's Avatar
    Join Date
    Nov 2012
    Posts
    20,171
    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.

  12. #12
    Junior Member
    Join Date
    Jan 2017
    Posts
    3

    Question

    I've been struggling this issue for some time. Have there been any improvement yet? There still some delay when using `Ethernet.setRetransmissionCount(0)`

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •