Open multiple sockets on Arduino Ethernet

Hello,
I’m actually working on an ARP like table :
The thing is quite simple :

  1. Passively listen to trafic to detect who is active on the network
  2. Emit data to specific active node

I didn’t found satisfying function in Ethernet library : they require a connection, that is not exactly a passive listening of the network ^^
So I found a raw ethernet method directly coming from the W5100 controller.
This work fine alone.

Then for the emitting part I decided to directly use the UDP sending method proposed in the Ethernet library, it is quite simple and avoid me to manually define MAC CRC, IP header CRC, and other painfull stuf like ARP resolution…
This UDP sending method works also fine alone.

The problem occurs when the two methods/functions are used in the same sketch.
Here is the debug example I use :

#include <SPI.h>         // needed for Ethernet library communication with the W5100 (Arduino ver>0018)
#include <Ethernet.h>
#include <utility/w5100.h>
#include <EthernetUdp.h> 
 
// our listening socket that will be opened in RAW mode 
SOCKET s; 

//socket raw IP
//SOCKET t;

byte rbuf[1500+14]; // receive buffer 
int rbuflen; // length of data to receive

/*
byte sbuf[1500+14]; // send buffer 
int sbuflen = 64; // length of data to send
*/

int i;

byte IP_source[] = {192, 168, 1, 177};
byte MAC_source[] = {0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
unsigned int local_port = 27225;

byte IP_dest[] = {192, 168, 1, 180};

unsigned int remote_port = 27226;      // local port to listen on

byte data = 255;

EthernetUDP Udp;


void setup() {
 
// initialize the w5100 chip and open a RAW socket  
  W5100.init();

 //open the RAW_ethernet listening socket  
  W5100.writeSnMR(s, SnMR::MACRAW); 
  W5100.execCmdSn(s, Sock_OPEN);
 
 //open the RAW_IP listening socket  
   /*
   W5100.writeSnMR(t, SnMR::IPRAW); 
   W5100.execCmdSn(t, Sock_OPEN);
   */

 //open udp socket
  Ethernet.begin(MAC_source,IP_source);
  Udp.begin(local_port);

  
//init of serial line (feedback)
   Serial.begin(9600);

}



void loop() {

Serial.println("test");

// check if we have received something
  rbuflen = W5100.getRXReceivedSize(s);

//Detection of incoming packet  
if (rbuflen>0) {
  // receive packet 
  W5100.recv_data_processing(s, rbuf, rbuflen);
  W5100.execCmdSn(s, Sock_RECV);
   
    
  Serial.println("frame captured");
  Serial.println("dest MAC addresse"); 
   // offset 2 ... because the first two bytes in 'rbuf' contain the packet length
  for (i=2; i<6; i=i+1)
     {     
    Serial.println(rbuf[i]);
     }
     
  Serial.println("Dest MAC addresse");    
   for (i=8; i<14; i=i+1)
     {
    Serial.println(rbuf[i]);
     }  
   
   Serial.println("Type");  
    for (i=14; i<16; i=i+1)
     {
      Serial.println(rbuf[i]);
     } 
     
   Serial.println("Identifiant IP");  
    for (i=18; i<20; i=i+1)
     {
      Serial.println(rbuf[i]);
     }
     
   Serial.println("IP src");  
    for (i=28; i<32; i=i+1)
     {
      Serial.println(rbuf[i]);
     } 
 
   Serial.println("IP dest");  
    for (i=32; i<36; i=i+1)
     {
      Serial.println(rbuf[i]);
     }
}

}

As you can see I don’t even send effectively frame, I just opened both sockets.
At the begining of the loop, if put a little test print to check if the program is running.

So in this example, with both sockets opened, nothing appears on the serial line.
If i go backward and comment the opening of the udp socket

 //open udp socket
  //Ethernet.begin(MAC_source,IP_source);
  //Udp.begin(local_port);

Then the serial line gets active and start printing the “test” message.

The problem also occurs if I open a RAW ethernet socket and a RAW IP socket throught W5100 methods…
(you can test it with the quoted init methods)

The questions are :
Is that normal doctor ?
What is the problem ?
Is there a way to create two different socket operating at different layers ?

Somebody advised me to close the first listening socket before opening the socket used for emission, but I fear that the setup is only runned once and that a closed socket cannot be reopened in another cycle of the loop …

I may be not very clear, so do not hesitate to ask for more accurate description of the problem :*

What sort of Arduino are you running this on? I ask as the Uno only has 2K memory iirc and you use 1514 for a buffer plus whatever the w5100 uses along with the various other arrays and variables you have.

Exactly, this is an arduino uno with an ethernet shield :

http://boutique.semageek.com/fr/kits-arduino/47-arduino-uno-ethernet.html

So somebody advised me to close the listening socket before opening the emitting socket.

This looks like a little bit tricky and I fear that this will be dificult to perform as the initialization of socket is done in the setup() part of the sketch.

But maybe it is possible to initialize the socket directly in the loop() of the sketch ?

PS : Finally size (of buffer) may matter :grin: