Pages: [1]   Go Down
Author Topic: UDP library bug?  (Read 1199 times)
0 Members and 1 Guest are viewing this topic.
0
Online Online
Shannon Member
****
Karma: 130
Posts: 10464
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
Tommaso, in the Italian forum, is doing some experiment using the UDP lib.
He found out that if at least one of the receiver is invalid (non existent, offline, etc..) the time for sending a message is 10 time slower...

test skecth:
Code:
#include <SPI.h>         // needed for Arduino versions later than 0018
#include <Ethernet.h>
#include <Udp.h>         // UDP library from: bjoern@cs.stanford.edu 12/30/2008

byte mac[] = {  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 192,168,0,202 };
unsigned int localPort = 8888;      // local port to listen on

byte remoteIp[] = { 192,168,0,201 };
byte remoteIp2[] = {192,168,0,203 };

unsigned int remotePort = 8888; // holds received packet's originating port
unsigned int remotePort2 = 8889;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE]; //buffer to hold incoming packet,

char invio[3];


int stati = 0;


void setup() {


 

  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop() {

   stati = 10;
   itoa(stati,invio,10);

   Serial.print("Ho inviato");
   Serial.println(invio);

   Udp.sendPacket( invio, remoteIp, remotePort);

   Udp.sendPacket( invio, remoteIp2, remotePort2);
   
  delay(200);
}

I have take a look at what is going on...
and i think the error is in Socket.cpp:
Code:
/**
 * @brief This function is an application I/F function which is used to send the data for other then TCP mode.
 * Unlike TCP transmission, The peer's destination address and the port is needed.
 *
 * @return This function return send data size for success else -1.
 */
uint16_t sendto(SOCKET s, const uint8_t *buf, uint16_t len, uint8_t *addr, uint16_t port)
{
  uint16_t ret=0;

  if (len > W5100.SSIZE) ret = W5100.SSIZE; // check size not to exceed MAX size.
  else ret = len;

  if
    (
  ((addr[0] == 0x00) && (addr[1] == 0x00) && (addr[2] == 0x00) && (addr[3] == 0x00)) ||
    ((port == 0x00)) ||(ret == 0)
    )
  {
    /* +2008.01 [bj] : added return value */
    ret = 0;
  }
  else
  {
    W5100.writeSnDIPR(s, addr);
    W5100.writeSnDPORT(s, port);

    // copy data
    W5100.send_data_processing(s, (uint8_t *)buf, ret);
    W5100.execCmdSn(s, Sock_SEND);

    /* +2008.01 bj */
    while ( (W5100.readSnIR(s) & SnIR::SEND_OK) != SnIR::SEND_OK )
    {
      if (W5100.readSnIR(s) & SnIR::TIMEOUT)
      {
        /* +2008.01 [bj]: clear interrupt */
        W5100.writeSnIR(s, (SnIR::SEND_OK | SnIR::TIMEOUT)); /* clear SEND_OK & TIMEOUT */
        return 0;
      }
    }

    /* +2008.01 bj */
    W5100.writeSnIR(s, SnIR::SEND_OK);
  }
  return ret;
}

as you can see there is a while that wait for response or timeout.. but this is wrong in UDP, isn't it?
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 216
Posts: 13668
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
as you can see there is a while that wait for response or timeout.. but this is wrong in UDP, isn't it?
Not dived into it but the class is software talking to hardware.
If I see it correctly, the code waits until the ethernet chip sends the UDP packet, not until an acknowledge/response is received (like TCP). Not strictly necessary for UDP sec but it prevents overwritten buffers in the chip I guess .

Makes sense?

Rob.
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10464
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

make sense, but doesn't explain the slowdown.
I'm sorry but I don't have ethernet or wifi shield, so i can't understand better where the problem is...

need help from skilled people :-)
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 216
Posts: 13668
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

You need to understand that UDP and TCP packets are wrapped up in another layer before they are send over the wire. This additional layer adds ethernet addresses (+++) to the packet, not to be mangled with internetaddresses or IP adresses. Ethernet addresses are like the mac address 6 HEX digits . Open a windows command shell and enter "arp -a " (prob works under linux and mac too) to see the difference. The delay is probably caused by the chip as it cannot find the right ethernetaddress to add, so it will not send the packet causing a timeout.

That said, I might be something completely different as I don't know the details of how the chip works.

Comer wrote some good books about how the internet protocols work in depth - http://www.amazon.com/Douglas-E.-Comer/e/B000AQ4HHG

Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10464
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

i know a little about the iso-osi standard, but this sound strange to me... if you have a multicast UDP packet, what mac should it use? and for build a packet it has to ask know in advance the mac of reciver?
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 216
Posts: 13668
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Good questions that s why I added the link to the books smiley
- For multicast you need additional protocols - IIRC - to handle the subscriptions, your router /gateway / ISP needs to support multicast. I expect it will use your routers mac address. [been long time I read the books myself]

Quote
and for build a packet it has to ask know in advance the mac of reciver?
No it needs to know the first MAC of the first HOP. To get an idea type : tracert -d www.google.com at a command promtpt to find the hops

If you really want to know the details, please buy and read the books, they explain it far better than I can.

Rob
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

0
Online Online
Shannon Member
****
Karma: 130
Posts: 10464
:(){:|:&};:
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

ok, so the slowdown problem should be only if gateway is down (it's the first hop, no?) not when the receiver is down...
Logged

sei nuovo? non sai da dove partire? leggi qui: http://playground.arduino.cc/Italiano/Newbie

Global Moderator
Netherlands
Online Online
Shannon Member
*****
Karma: 216
Posts: 13668
In theory there is no difference between theory and practice, however in practice there are many...
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

No not  quite - You need to understand the Address Resolution Protocol ARP. The chip has to know to which hop he has to send a packet with a certain IP address.

- http://tools.ietf.org/html/rfc826
Logged

Rob Tillaart

Nederlandse sectie - http://arduino.cc/forum/index.php/board,77.0.html -
(Please do not PM for private consultancy)

Offline Offline
Newbie
*
Karma: 0
Posts: 11
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

In my case the sendto() doesn't return at all sometimes. I'm trying to send an NTP datagram to ptbtime1.ptb.de. I think I've initialised the Ethernet and the socket correctly. I'm still looking into the matter, but seemingly neither the SnIR::SEND_OK nor the SnIR::TIMEOUT get set, the SnIR simply stays 0 all the time. This is from the setup() routine, but that shouldn't matter, should it? If I send the datagram to a PC on my local network, everything is fine.

Who is bj that made this code in 2008? Maybe he can help to understand the logic, and see whether a forced bailout after so-and-so many iterations would not be a good idea ...

Kind regards,
Sebastian
Logged

Pages: [1]   Go Up
Jump to: