im looking at the example from HERE. i just have one question. What exactly is happening here,
int len = Udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0; //? why?
}
Heres the whole program. i understand everything except that part
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>
const char* ssid = "********";
const char* password = "********";
WiFiUDP Udp;
unsigned int localUdpPort = 4210; // local port to listen on
char incomingPacket[255]; // buffer for incoming packets
char replyPacket[] = "Hi there! Got the message :-)"; // a reply string to send back
void setup()
{
Serial.begin(115200);
Serial.println();
Serial.printf("Connecting to %s ", ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println(" connected");
Udp.begin(localUdpPort);
Serial.printf("Now listening at IP %s, UDP port %d\n", WiFi.localIP().toString().c_str(), localUdpPort);
}
void loop()
{
int packetSize = Udp.parsePacket();
if (packetSize)
{
// receive incoming UDP packets
Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = Udp.read(incomingPacket, 255);
if (len > 0)
{
incomingPacket[len] = 0;
}
Serial.printf("UDP packet contents: %s\n", incomingPacket);
// send back a reply, to the IP address and port we got the packet from
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(replyPacket);
Udp.endPacket();
}
}
if Udp.parsePacket(); returns the size, then wahts happening with "int len"? why is 255 passed to it?
It's printing whatever was in the UDP packet to the serial port. The packet content is stored in a char array. Serial.print expects a C string, i.e. a zero terminated array of char. The mystery code ensures that it is zero terminated.
UDP packets can be huge. Arduino doesn't have much ram so when you read a packet, you need to tell the library how big the buffer is that you have set aside for it. Then it'll avoid overflowing your array if it sees a larger packet.
notsolowki:
Thankyou, okay so were adding the terminating character to incommingPacket. but why is 255 passed as an arg in this expression,
int len = Udp.read(incomingPacket, 255);
As stated, it's telling the maximum number of characters to read. The source code is always the definitive answer to how functions work. That's were I usually start. Take a look and you can find out a lot of this stuff on your own. Inside 'WiFiUdp.h', you'll find the prototype for this function along with some comments:
int read(unsigned char* buffer, size_t len) override;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
gfvalvo:
As stated, it's telling the maximum number of characters to read. The source code is always the definitive answer to how functions work. That's were I usually start. Take a look and you can find out a lot of this stuff on your own. Inside 'WiFiUdp.h', you'll find the prototype for this function along with some comments:
int read(unsigned char* buffer, size_t len) override;
// Read up to len characters from the current packet and place them into buffer
// Returns the number of characters read, or 0 if none are available
read up to len characters i think means read up to how every many bytes or the length. but i got confused when i seen 255. so 255 is just to prevent overflows? OR Just in case the packet is larger than 255, it wont read more than 255. because i'm going to need to know the length of the actual data in order to extract verification bytes from beginning and end of it.
I did read the classes it just didn't make sense to me still. but now i think i get it
If you're processing UDP packets, you probably know how big they're going to be, but you also want to defend against overflow in case some other process is sending them too. Overflow will probably crash your program or at least make it behave in unexpected ways.
This isn't restricted to UDP, whenever you're buffering data, it's a sensible practice to ensure that you don't exceed the bounds (at either end) of that buffer.
wildbill:
If you're processing UDP packets, you probably know how big they're going to be, but you also want to defend against overflow in case some other process is sending them too. Overflow will probably crash your program or at least make it behave in unexpected ways.
This isn't restricted to UDP, whenever you're buffering data, it's a sensible practice to ensure that you don't exceed the bounds (at either end) of that buffer.
Am i missing something. if i send a 32byte message will it not show up as a 32byte message?
in my UDP communications program i'm trying to make i want to verify the data being sent by the sender. I want to add the "NODE01" to the beginning and the end of the bytes im trying to send. Currently im sending like this,
if (millis() - now >= 900) {
now = millis();
now2 = millis();
Udp.beginPacket(Server, ServerPort);
Udp.write((char*)&localData, sizeof(localData));
Udp.endPacket();
digitalWrite(5,HIGH);
}
How can i add that byte string to the beginning and end of the bytes being sent?
in my previous program i used somthing like this,
if (millis() - now >= 500) {
if (client->space() > 32 && client->canSend()) {
client->add("NODE02", 7); //add verification1
client->add((char *)&st, sizeof(sampleStruct));
client->add("NODE02", 7); //add verification2
client->send();
Serial.println("sent");
//client->free();
}
EDIT: im going to try to printf it to a char array and add everything together and send that to see if it works
I'm going to need to learn how to use those delimiters. i use Robin2's serial example#5 and i have never really needed anything else. Also will this code always send buffer as 64 bytes of will the size automatically be determined up to 64 bytes?
I'm still having a bit of trouble with the sizeof(incomingPacket). i have successfully extracted the firt 7 bytes of the packet but now i need to get to the 7 bytes after the data structure. in theory this would be the last 7 bytes but in this case i don't know what to do?
veryfyStart i cant read just fine. but its verifyEnd im having trouble finding the right bytes. i wish len would just return the size of the data plus the extra 14 byte i send with it. i cant veryfy what the length actually is.
int packetSize = Udp.parsePacket();
if (packetSize)
{
// receive incoming UDP packets
//Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = Udp.read(incomingPacket,800);
sprintf (verifyStart, (char*)incomingPacket, 7 );
sprintf (verifyEnd, (char *)incomingPacket + sizeof(incomingPacket) - 7, 7 ); //not working
Serial.println("hello");
Serial.println(verifyStart);
Serial.println(verifyEnd);
// Serial.printf("UDP packet contents: %s\n", incomingPacket);
digitalWrite(5, HIGH);
the char array "buffer" i initialized as [64] but this is the sending code,
if (millis() - now >= 900) {
now = millis();
now2 = millis();
char buffer[64];
sprintf(buffer, "NODE01", &localData, "NODE01");
Udp.beginPacket(Server, ServerPort);
Udp.write((char*)&buffer, sizeof(buffer));
Udp.endPacket();
digitalWrite(5, HIGH);
}
it worked i must mis understood that write must be adding to a buffer itself. however im having trouble with the receiving length and the way this code is now verifyStart and veryfyEnd print the same bytes?
int packetSize = Udp.parsePacket();
if (packetSize)
{
// receive incoming UDP packets
//Serial.printf("Received %d bytes from %s, port %d\n", packetSize, Udp.remoteIP().toString().c_str(), Udp.remotePort());
int len = Udp.read(incomingPacket,800);
sprintf (verifyStart, (char*)incomingPacket, 7 );
sprintf (verifyEnd, (char *)incomingPacket + sizeof(packetSize) - 11, 7 );
Serial.println("hello");
Serial.println(verifyStart);
Serial.println(verifyEnd);
// Serial.printf("UDP packet contents: %s\n", incomingPacket);
digitalWrite(5, HIGH);
}
I chose 800 as that arg because i thought the max size char array is 1000 but im probably wrong.
EDIT: when i serial.println length it says 24. and i thought would work,