Arduino Ethernet Board UDP communication between C# and Arduino

Hi folks. First let me say this is my first post. I am fairly new to Arduino and fairly new to network programming in general. That being said, I'll try to make my question clear.
I have an Arduino Ethernet Board connected to a hub and a PC (Windows 8) connected to an Ethernet port (different subnets) FWIW, the PC is an IPSEC Boundary machine.
My goal is simple proof-of-concept wherein I am trying to send a simple command to the Arduino from the C# program. The Arduino processes the input: '1' will turn the LED at PIN 9 on, '0' turns it off. After Arduino processes the command character, it should return information to the calling C# program.
The first half works famously: Arduino receives the command character and turns the LED on or off as expected. However, I cannot get anything back to the C# program.
I've looked at Wireshark capture and the Arduino Source keeps reporting "Destination unreachable (Port unreachable)" while the PC Source reports "Unknown 243" followed by "Identity Protection (Main Mode)". I've tried looking both of these messages up without much luck.
I am inserting both the Arduino sketch and the C# code below. Please note that I've been working on this for a couple weeks and while I've tried to clean up the code before posting it, it may look a bit messy...

Sketch:

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

//MAC on board: 90-A2-DA-0E-D9-91
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0E, 0xD9, 0x91 };
IPAddress ip(172, 29, 38, 80);

int led = 9;

unsigned int localPort = 8888;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

//Initialize EthernetUDP
EthernetUDP Udp;

char replyMsg[] = "Value Received";
char errMsg[] = "Problem";

void setup()
{
  //Start Ethernet and UDP
  pinMode(led, OUTPUT);
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop()
{
  int packetSize = Udp.parsePacket();
  char noNo[] = "Hello";

  if(packetSize)
  {
    for(int i=0;i<UDP_TX_PACKET_MAX_SIZE;i++) packetBuffer[i] = 0;

    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    char valIn[packetSize]; // = packetBuffer;
    
    for(int i = 0; i < packetSize; i++)
    {
      valIn[i] = packetBuffer[i];
    }
    String theVal = valIn;

    int strIndex = theVal.length();

    if(theVal.substring(0,1) == "1")
    {
      Serial.println(Udp.remotePort());
      Serial.println(Udp.remoteIP());
      Serial.println("On ");
      digitalWrite(led, HIGH);
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.write("Hello");
      Udp.endPacket();
    }
    else if(theVal.substring(0,1) == "0")
    {
      Serial.println(Udp.remotePort());
      Serial.println(Udp.remoteIP());
      Serial.println("Off");
      digitalWrite(led, LOW);
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.write("GoodBye");
      Udp.endPacket();      
    }
    else
    {
      Serial.println(Udp.remotePort());
      Serial.println(Udp.remoteIP());
      Serial.println("Err");
      Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
      Udp.write(errMsg);
      Udp.endPacket();
    }
  }
  delay(10);
}

C# code:

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace SendReceiveUDP
{
    class Program
    {
        static void Main(string[] args)
        {
            //Port and IP Data for Socket Client
            string IP = "172.29.38.80";
            int port = 8888;

            string inputVal = "1";
            while (inputVal != string.Empty)
            {
                var udpClient = new UdpClient();
                var clientReturn = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                inputVal = string.Empty;
                inputVal = Console.ReadLine();

                if (inputVal == string.Empty) break;
                try
                {
                    int inputInt;
                    int.TryParse(inputVal, out inputInt);

                    udpClient.Connect(IPAddress.Parse(IP), port);

                    // Sends a message to the host to which you have connected.
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(inputInt.ToString());

                    udpClient.Send(sendBytes, sendBytes.Length);

                    //System.Threading.Thread.Sleep(5000);

                    //IPEndPoint object will allow us to read datagrams sent from any source.
                    int newport = ((IPEndPoint)udpClient.Client.LocalEndPoint).Port;

                    Console.WriteLine("newport= " + newport);

                    var remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);

                    Console.WriteLine("Parsed IP= " + remoteIpEndPoint.Address);
                    string returnData = string.Empty;
                    // Blocks until a message returns on this socket from a remote host.
                    try
                    {
                        try
                        {
                            clientReturn.Bind(remoteIpEndPoint);
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine("Trying to Bind: " + ex.Message);
                        }

                        Byte[] receiveBytes = new byte[1024];

                        //The C# code stops execution here, waiting for a packet
                        clientReturn.Receive(receiveBytes, 0, receiveBytes.Length,SocketFlags.None);

                        returnData = Encoding.ASCII.GetString(receiveBytes);
                    }
                    catch (Exception ex)
                    {
                        Console.WriteLine("Trying to Receive: " + ex.Message);
                    }

                    // Uses the IPEndPoint object to determine which of these two hosts responded.
                    Console.WriteLine("Message Received: " +
                                      returnData.ToString());
                    Console.WriteLine("Send from: " +
                                      remoteIpEndPoint.Address.ToString() +
                                      " on their port number " +
                                      remoteIpEndPoint.Port.ToString());

                    udpClient.Close();
                    clientReturn.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            }
        }
    }
}

Note: I have also tried running the C# code from a PC on the same subnet as the Arduino and while it processes the command character described and the C# code hangs where noted in the code block above, all I see in Wireshark is:
Source PC: Info = Source port: 54463 Destination port: ddi-udp-1
Source Arduino: Info = Source port: ddi-udp-1 Destination port: 54463

Any and all help and/or recommendations are appreciated!

1 Like

Quick note to anyone looking at this post: I've worked out my fix. Will post soon as able.

I've been getting a very similar error, my C# code will send the integer and perform the command on the arduino side but Arduino will not communicate back with my device. How did you possibly fix it I've been trying to for about a three days now.

ceesharpie, here is the code I used:

C#

using System;
using System.Text;
using System.Net;
using System.Net.Sockets;

namespace SendReceiveUDP
{
    class Program
    {
        static void Main(string[] args)
        {
            //Port and IP Data for Socket Client
            var IP = IPAddress.Parse("172.29.38.80");

            int port = 8888;

            string inputVal = "1";
            while (inputVal != string.Empty)
            {
                var udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
                var sendEndPoint = new IPEndPoint(IP, port);
                var receiveEndPoint = new IPEndPoint(IP, port);

                var clientReturn = new UdpClient(port);
                inputVal = string.Empty;
                inputVal = Console.ReadLine();

                if (inputVal == string.Empty) break;
                try
                {
                    int inputInt;
                    int.TryParse(inputVal, out inputInt);

                    // Sends a message to the host to which you have connected.
                    Byte[] sendBytes = Encoding.ASCII.GetBytes(inputInt.ToString());

                    udpClient.SendTo(sendBytes, sendEndPoint);
                    string returnData = string.Empty;
                    // Blocks until a message returns on this socket from a remote host.

                    Byte[] receiveBytes;

                    receiveBytes = clientReturn.Receive(ref receiveEndPoint);
                    returnData = Encoding.ASCII.GetString(receiveBytes);

                    // Uses the IPEndPoint object to determine which of these two hosts responded.
                    Console.WriteLine("Message Received: " +
                                      returnData.ToString());

                    if (inputInt == 3)
                    {
                        receiveBytes = clientReturn.Receive(ref receiveEndPoint);
                        returnData = Encoding.ASCII.GetString(receiveBytes);

                        // Uses the IPEndPoint object to determine which of these two hosts responded.
                        Console.WriteLine("Message Received: " +
                                          returnData.ToString());
                    }

                    udpClient.Close();
                    clientReturn.Close();
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                }
            }
        }
    }
}

Arduino sketch:

#include <SPI.h>
#include <Ethernet.h>
#include <EthernetUdp.h>

//MAC on board: 90-A2-DA-0E-D9-91
byte mac[] = {
  0x90, 0xA2, 0xDA, 0x0E, 0xD9, 0x91 };
IPAddress ip(172, 29, 38, 80);

int led = 9;

unsigned int localPort = 8888;

char packetBuffer[UDP_TX_PACKET_MAX_SIZE];

//Initialize EthernetUDP
EthernetUDP Udp;

char replyMsg[] = "Value Received";
char errMsg[] = "Problem";

void setup()
{
  //Start Ethernet and UDP
  pinMode(led, OUTPUT);
  Ethernet.begin(mac,ip);
  Udp.begin(localPort);

  Serial.begin(9600);
}

void loop()
{
  int packetSize = Udp.parsePacket();
  char noNo[] = "Hello";

  if(packetSize)
  {
    for(int i=0;i<UDP_TX_PACKET_MAX_SIZE;i++) packetBuffer[i] = 0;

    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);

    char valIn[packetSize]; // = packetBuffer;
    
    for(int i = 0; i < packetSize; i++)
    {
      valIn[i] = packetBuffer[i];
    }
    String theVal = valIn;

    int strIndex = theVal.length();

    if(theVal.substring(0,1) == "1")
    {
//      Serial.println(Udp.remotePort());
//      Serial.println(Udp.remoteIP());
//      Serial.println("On ");
      digitalWrite(led, HIGH);
      Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write("Flame On!");
      Udp.endPacket();
    }
    else if(theVal.substring(0,1) == "0")
    {
//      Serial.println(Udp.remotePort());
//      Serial.println(Udp.remoteIP());
//      Serial.println("Off");
      digitalWrite(led, LOW);
      Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write("Flame off.");
      Udp.endPacket();      
    }
    else if(theVal.substring(0,1) == "3")
    //Blinks the LED - off, on; ending off
    {
//      Serial.println(Udp.remotePort());
//      Serial.println(Udp.remoteIP());
//      Serial.println("Blinking");
      digitalWrite(led, LOW);
      Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write("Fade in...");
      Udp.endPacket();
      int i = 1;
      for(int x = 0; x > -1; x = x + i)
      {
        analogWrite(led, x);
        if(x == 255) i = -1;
        delay(20);
//        digitalWrite(led, HIGH);
//        delay(2000);
      }
            Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write("Fade out...");
      Udp.endPacket();
      digitalWrite(led, LOW);
    }
    else
    {
//      Serial.println(Udp.remotePort());
//      Serial.println(Udp.remoteIP());
//      Serial.println("Err");
      Udp.beginPacket(Udp.remoteIP(), 8888);
      Udp.write(errMsg);
      Udp.endPacket();
    }
  }
  delay(10);
}

Please ignore the commented lines in the sketch. Also, if you compare it to the original sketch, you will see I made some functional changes (Fade in and Fade out of the LED, rather than on and off).

Hope this helps!

thanks for the post max. Really helped me a lot.

this is the error am getting in the script at the 8th line. any help please?

the namespace 'SendReceiveUDP' already contains a definition for 'Program'

You can NOT name your class Program. You can use ANY other name. That is basic C#.

PaulS:
You can NOT name your class Program. You can use ANY other name. That is basic C#.

am new to c# so dont know much. the program uploaded here writes class program, so what shal i do?

so what shal i do?

Zip up your entire solution folder and attach it here.

There is a lot about that program that I do not like. new Socket returns a Socket instance. Storing that in a var is a poor idea. The same holds true for every other var type variable that you have. Use the proper types.

                    Byte[] sendBytes = Encoding.ASCII.GetBytes(inputInt.ToString());

You just converted a string containing an integer representation to an int. It is silly to convert that int back to a string.

am doing nothing just copied this c# program and made a script in Unity but it doesn't works. First it was about namespace now it says that i have to use monobehaviour but how?

now it says that i have to use monobehaviour but how?

Would you like 1/10th of an answer? If not, why do you post 1/10th of an error message?

problem is i dont know how to use this script

this is what i get

this is what i get

That is a problem between Unity and the C# app. It has NOTHING to do with the Arduino.

yes but if i solve this then and only then i will be able to get an output on the arduino

yes but if i solve this

Solving that will involve the Unity forum, not the Arduino forum.

can you help or not? if not then thank you if can then please do rather than kicking me around

can you help or not?

With your Unity problem? No. Do you routinely ask on the Unity forum for help with Arduino code?

check out this forum you would see both of the codes here and it is interfacing. Don't try to be a jerk and create a disrespectable image of your's in someone's head.