Hi,
I am having intermittent problems using QNEthernet to receive UDP messages on a Teensy 4.1
I am firing UDP messages (of 6008 bytes) from a C# test program at the Teensy which is running the sketch below
It works fine for a while, printing out a message at every multiple of 10000 packets
Then after some variable amount of time/ packets, it just hangs
I know the C# application is still sending packets because if I reset the Teensy, it start receiving again
When it hangs, it must be receiving -1 from parsePacket() because I don't get a message logging any other negative return code
I am assuming the EthernetUdp object has failed in some way?
Is there a way to detect this so that I could then perhaps call .begin() again, assuming that would enable it to recover?
If I put a 1ms delay in the client sending loop (between each packet being sent), it seems to not fail but maybe I just did not test it for long enough
I had thought about increasing the queue length?
I am aware that 6008 bytes is over 4 times the size of the MTU max packetr size of 1500 bytes. However the packet splitting/ combining clearly seems to be working to some degree at least?
Thanks
The number of packets seems to vary
HTML Code:
#include <QNEthernet.h>
using namespace qindesign::network;
const uint32_t kDHCPTimeout = 10000; // 10 seconds
const uint32_t PayloadLength = 6000;
const uint32_t LocalPort = 8002;
struct __attribute__((packed)) T_MessageHeader
{
uint32_t messageId;
uint32_t payloadLength;
};
struct __attribute__((packed)) T_TestMessage
{
T_MessageHeader messageHeader;
char payload[PayloadLength];
};
union __attribute__((packed)) T_MessageBuffer
{
T_TestMessage testMessage;
char buffer[sizeof(T_TestMessage)];
};
EthernetUDP udp;
unsigned long packetCount = 0;
void setup()
{
Serial.begin(115200);
while (!Serial && millis() < 4000)
{
// Wait for Serial to initialize
}
stdPrint = &Serial; // Make printf work (a QNEthernet feature)
printf("Starting...\r\n");
uint8_t mac[6];
Ethernet.macAddress(mac); // This is informative; it retrieves, not sets
printf("MAC = %02x:%02x:%02x:%02x:%02x:%02x\r\n",
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
printf("Starting Ethernet with DHCP...\r\n");
if (!Ethernet.begin())
{
printf("Failed to start Ethernet\r\n");
return;
}
if (!Ethernet.waitForLocalIP(kDHCPTimeout))
{
printf("Failed to get IP address from DHCP\r\n");
return;
}
IPAddress ip = Ethernet.localIP();
printf(" Local IP = %u.%u.%u.%u\r\n", ip[0], ip[1], ip[2], ip[3]);
ip = Ethernet.subnetMask();
printf(" Subnet mask = %u.%u.%u.%u\r\n", ip[0], ip[1], ip[2], ip[3]);
ip = Ethernet.gatewayIP();
printf(" Gateway = %u.%u.%u.%u\r\n", ip[0], ip[1], ip[2], ip[3]);
ip = Ethernet.dnsServerIP();
printf(" DNS = %u.%u.%u.%u\r\n", ip[0], ip[1], ip[2], ip[3]);
// Start UDP listening on the NTP port
udp.begin(LocalPort);
}
void loop()
{
int packetSize = udp.parsePacket();
if ((packetSize < 0) && (packetSize != -1))
{
printf("Return code: %d\r\n", packetSize);
}
if (packetSize > 0)
{
if (packetSize > (int) sizeof(T_TestMessage))
{
printf("Packet size error (expected: %u, actual: %u)\r\n", sizeof(T_TestMessage), packetSize);
}
else
{
T_MessageBuffer messageBuffer;;
int dataCount = udp.read(messageBuffer.buffer, packetSize);
if (dataCount != packetSize)
{
printf("Packet read error (expected: %u, actual: %u)\r\n", packetSize, dataCount);
}
else
{
packetCount++;
if ((packetCount % 10000) == 0)
{
printf("Packet count: %lu\r\n", packetCount);
}
}
}
}
}