Sending and Receiving String via UDP example

I am trying to establish ethernet udp communication between my Pc and arduino. I am following this example: https://docs.arduino.cc/tutorials/ethernet-shield-rev2/udp-send-receive-string . I am using c/c++ for my project bu the client code provided in the example is in Processing language. Anyone has an idea how I could implement the below snippet in c/c++?

Processing sketch to run with this example

// Processing UDP example to send and receive string data from Arduino
// press any key to send the "Hello Arduino" message

 import hypermedia.net.*;

 UDP udp;  // define the UDP object


 void setup() {
 udp = new UDP( this, 6000 );  // create a new datagram connection on port 6000
 //udp.log( true ); 		// <-- printout the connection activity
 udp.listen( true );           // and wait for incoming message
 }

 void draw()
 {
 }

 void keyPressed() {
 String ip       = "192.168.1.177";	// the remote IP address
 int port        = 8888;		// the destination port

 udp.send("Hello World", ip, port );   // the message to send

 }

 void receive( byte[] data ) { 			// <-- default handler
 //void receive( byte[] data, String ip, int port ) {	// <-- extended handler

 for(int i=0; i < data.length; i++)
 print(char(data[i]));
 println();
 }
1 Like

Did you have a look at some of the tutorials?

There are many more.

1 Like

Ok all of these topic cover how to establish SERVER on arduino. My question is what UDP CLIENT c/c++ code should run on my PC so that I can communicate with arduino. I know how to make my arduino send and receive strings but i dont know what code my computer should run to do the same.

More specifically I want a c/c++ code for my PC so that can write a UDP packet on a local port and sent back a packet on a specified outgoing port. All so that my arduino can receive these packets.

Sth like this UDP Server-Client implementation in C++ - GeeksforGeeks but this one is not working for me:(

I see, and you need it in C++ because you have to embed it in a larger project, or is this something stand alone? If so, there are command line tools available that can do this already (like netcat).

1 Like

Exactly, it is a larger project where communication is just one piece.

Okay. The client in your link compiles just fine for me, so if you can share the error messages you get, perhaps I can see what the problem is.

1 Like

Ok so the issue is that if you run client and server from the "geeks" link I sended, compile them and run two separate linux terminals you can have a udp communication between them. But when I run arduino code, specify some mac adress of the board and ip of local ethernet newtork and identical local port to listen to i do not have any communciation (no errors though).

server:


/*
 UDPSendReceiveString:
 This sketch receives UDP message strings, prints them to the serial port
 and sends an "acknowledge" string back to the sender
 */


#include <NativeEthernet.h>
#include <NativeEthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0x4c, 0xed, 0xfb, 0xc4, 0x9d, 0x2e
};

IPAddress ip(131, 203, 101, 128); //based on the enp0s31f6, CHANGED for security

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged and received";        // a string to send back

int led = 13;

void Blink(); //make diode blink

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() {

  //just to check if this is installed correctly
  pinMode(led, OUTPUT);
  // start the Ethernet
  Ethernet.begin(mac, ip); //supports DHCP and IP is obtained automatically

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
    
    }
  else
  {
    Serial.println("Ethernet shield detected");
  }
  
  
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }
   else
  {
    Serial.println("cable detected");
  }

  // start UDP
  Udp.begin(localPort);
}


void loop() {
  Blink();
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i=0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
  delay(10);
}

void Blink(){
  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(100);               // wait for a second
}

and client

// Client side implementation of UDP client-server model
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>

#define PORT     8888
#define MAXLINE 1024

// Driver code
int main() {
    int sockfd;
    char buffer[MAXLINE];
    char *hello = "Hello from client";
    struct sockaddr_in     servaddr;

    // Creating socket file descriptor
    if ( (sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0 ) {
        perror("socket creation failed");
        exit(EXIT_FAILURE);
    }

    memset(&servaddr, 0, sizeof(servaddr));

    // Filling server information
    servaddr.sin_family = AF_INET;
    servaddr.sin_port = htons(PORT);
    servaddr.sin_addr.s_addr = INADDR_ANY;

    int n, len;

    sendto(sockfd, (const char *)hello, strlen(hello),
        MSG_CONFIRM, (const struct sockaddr *) &servaddr,
            sizeof(servaddr));
    printf("Hello message sent.\n");

    n = recvfrom(sockfd, (char *)buffer, MAXLINE,
                MSG_WAITALL, (struct sockaddr *) &servaddr,
                &len);
    buffer[n] = '\0';
    printf("Server : %s\n", buffer);

    close(sockfd);
    return 0;
}

Okay, I think these examples only work when both client and server are running on the same machine (they bind to IP 0.0.0.0).

What happens when you specify the IP address?

servaddr.sin_addr.s_addr = inet_addr("131.203.101.128");  // I think.
1 Like

It works, though only for one way communication! I was able to receive the signal to my arduino but I didnt got the response from arduino to my Pc. Namely:

char ReplyBuffer[] = "acknowledged and received";    
....
// send a reply to the IP address and port that sent us the packet we received
Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
Udp.write(ReplyBuffer);
Udp.endPacket();

was not received

What do you see on the serial monitor and are you running a firewall on your PC?

1 Like

Arduino Serial output:

Ethernet shield detected
cable detected
Received packet of size 17
From 131.203.220.164, port 26620
Contents:
Hello from client

each time I rerun the program the port number changes i.e.: port 26620, port 54836, port 54836 ... ip stays the same

If I run

sudo ufw status verbose
[sudo] password for username: 
Status: inactive

So i guess not

I got the client to work with the server example running on a different machine, so the PC side should be okay I guess.

Does your WiFi router have a firewall perhaps?

Can you run a tcpdump on your PC? E.g.,

tcpdump -n port 8888
2 Likes

Got some problems with the other account so now i am switching to this one. I need to run your command with sudo and then i get

11:50:31.686451 IP 10......41043 > 131.....128.8080: UDP, length 39

so I believe message is transmitted correctly (I am hiding IP adresses for the future) but still there is not message back to the pc

Maybe receiving port on the PC should be fixed as well?

No, that port is random as you have already noticed. I did not make any other changes in my working example either.

1 Like

So I understand that on your pc the code is working and the thinking is that there must be something wrong with my default network setting on my pc? Also i found this command server.write() Ethernet - server.write() - Arduino Reference maybe this would help?

I am not sure, it is quite hard to troubleshoot networking issues over a forum.

My setup is as follows:

  • The unmodified server example code is running on my router, I had to open port 8888 on its firewall.
  • The client example code is running on my laptop, there I use the IP of my router, analogous to what was mentioned in post #12.

If your board and your PC are on the same network, the setup should be rather similar. So my guess is that either:

  • There is a network device in between the board and the PC that blocks something.
  • The board is not sending a reply.
  • [edit] There might be a routing issue (can you ping the board)?
1 Like