Netduino home hardware projects downloads community

Jump to content


The Netduino forums have been replaced by new forums at community.wildernesslabs.co. This site has been preserved for archival purposes only and the ability to make new accounts or posts has been turned off.
Photo

Trying to recreate Arduino Code for Netduino, running into issues.

UDP Netduino Plus 2

  • Please log in to reply
4 replies to this topic

#1 berr08

berr08

    New Member

  • Members
  • Pip
  • 9 posts

Posted 05 August 2014 - 07:41 PM

Basically trying to setup my base functionality that I have used in all my arduino setups. 

 

I listen for a UDP message, then store the IP of the sender to send data back...idea is the application sends a GO commands over UDP the sensors start blaring and send json back to the application.

 

My issue iss the my socket.RemoteEndPoint is always saying the IPAddress is 0.0.0.0, so now I don't know where to send these messages to.

 

I'm using an example that I found on here for sending a receiving messages, it might be more than I need but just trying to get this working then remove the overkill.  So with the example below the listener.RemoteEndPoint is always saying 0.0.0.0 for the IP address.  Please help, just to better explain what I am doing I will put the arduino code below as well.

 

Thanks everyone, loving the netduino so far happy to get away from c/c++ mashup of the arduino!!!

#region The actual worker thread code
        /// <summary>
        /// This is a method which does the work of the worker thread.
        /// It is a bit like the program's main() function (but is not static).
        /// It waits (sleeps) for a UDP message to be received and passes it using the 
        /// supplied Interface.
        /// </summary>
        private void Main()
        {
            int bytes = 0;              // Holds number of bytes received
            var rxBuff = new byte[100]; // Holds received message

            // Convert IP address and port to an EndPoint
            IPEndPoint localEndPoint = new IPEndPoint(localIpAddress, port);

            // Create a "UDP" socket.
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            // Bind the socket to the local endpoint and listen for incoming UDP datagrams.
            try
            {
                listener.Bind(localEndPoint);
            }

            #region Catch exceptions
            catch (SocketException se)
            {
                SocketErrorCodes errorCode = (SocketErrorCodes)se.ErrorCode;

                switch (errorCode)
                {
                    case SocketErrorCodes.NetworkIsDown:
                        Debug.Print("Socket Exception on creation: NetworkIsDown");
                        break;
                    default:
                        Debug.Print("Socket Exception error: " + errorCode);
                        break;
                }
            }
            #endregion

            // TODO: If the network was down set up a timer to try again in a while.

            // Now that we have bound the socket to liste on the port, set a timeout for receive operations
            // We could just wait for ever, but having a timeout may be useful.
            listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, 1000);

            // Loop forever
            while (true)
            {
                bytes = 0;
                string cause = "unknown";

                // TODO: Currently we assume that one whole message will be received in one go
                // This may not be the case - consider using a length for the first byte and just 
                // read the length at first, followed by the correct amount of following bytes.
                // Without doing this we might receive less than a whole message or even 
                // parts of two messages.

                try
                {
                    //Debug.Print("Attempt to listen on " + localEndPoint.ToString());
                    bytes = listener.Receive(rxBuff);
                }
                #region catch exceptions
                catch (SocketException se)
                {
                    SocketErrorCodes errorCode = (SocketErrorCodes)se.ErrorCode;

                    switch (errorCode)
                    {
                        case SocketErrorCodes.NetworkIsDown:
                            // The network is not connected.
                            cause = "NetworkIsDown";
                            //Debug.Print("Socket Exception on receive: NetworkIsDown");
                            // Ignore error and carry on
                            break;

                        case SocketErrorCodes.ConnectionTimedOut:
                            // Connection timed out - e.g. nothing received
                            cause = "ConnectionTimedOut";
                            //Debug.Print("Socket Exception on receive: ConnectionTimedOut");
                            // Ignore error and carry on
                            break;

                        default:
                            Debug.Print("Socket Exception error: " + errorCode);
                            break;
                    }
                }
                #endregion

                if (bytes == 0)
                {
                    // Nothing may have been received if a timeout or an error occured.
                    Debug.Print("Nothing received: reason - " + cause);
                }
                else
                {
                    // Create a copy of the message that is the correct length
                    var msg = new byte[bytes];
                    for (int i = 0; i < bytes; i++)
                    {
                        msg[i] = rxBuff[i];
                    }
                    // Use interface to pass message to main thread
                    IPEndPoint ip = listener.RemoteEndPoint as IPEndPoint;
                    receiver.SetRemoteIP(ip.Address);
                    receiver.MsgRx(msg);
                }
            }
        }
        #endregion
void receiveData()
{ 
  remoteAddress = udp.remoteIP();            // Store IP as Remote IP
  
  udp.read(packetBuffer,5);                  // Read the packet into buffer
  
  // **For Testing Only**
  Serial.println(F("Contents:"));
  Serial.println(packetBuffer);
  
  // **Process Messages**
  if (strcmp(packetBuffer,"GOGO") == 0)
  {
      receivedStart = true;
  }
  else if (strcmp(packetBuffer,"STOP") == 0)
  {
      receivedStart = false;
  }
}


#2 berr08

berr08

    New Member

  • Members
  • Pip
  • 9 posts

Posted 06 August 2014 - 03:34 PM

I've had more time with this, so I started pulling the code apart making it simplier to understand (for the way I think atleast).  Starting with the receiving part, have the code done, but I'm having 2 issues.

  1. The RemoteEndPoint IP is still always 0.0.0.0, I need to figure out the IP that is sending the message so I can send the results back to that same IP.
  2. I have it working to read 1 message, but then everything craps out and even though it says there are 4 bytes available to read (once I send another message) the 'bytes = listener.Receive(rxBuff);' always return 0 and leaves the byte array empty.  Am I missing a step?

If anyone can help at all it would be much appreciated, hopefully I'm just missing a step somewhere?

 

Program.cs

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using Microsoft.SPOT.Hardware;
using SecretLabs.NETMF.Hardware;
using SecretLabs.NETMF.Hardware.Netduino;

using System.IO;
using Microsoft.SPOT.Net.NetworkInformation;

namespace UDPMag_NetduinoPlus2
{
    public class Program
    {
        private static IPAddress myIPAddress = null;
        private static int dataPort = 8888;
        private static UDPReceiver udpReceiver = null;
        public static void Main()
        {
            //Make Sure Network is setup.
            SetupTCPIPFromSD();

            //Setup Listener to handle incoming Commands, this runs a listener thread.
            udpReceiver = new UDPReceiver(new IPEndPoint(myIPAddress, dataPort));
            udpReceiver.OnMessageReceived += new UDPReceiver.MessageReceived(udpReceiver_OnMessageReceived);

            
            //The sender event is going to be created when we get our first message in the OnMessageReceived Handler.


            //Keep the thread alive as we are using all listeners and events.
            Thread.Sleep(Timeout.Infinite);
        }

        static void udpReceiver_OnMessageReceived(string message, IPEndPoint sender)
        {
            Debug.Print(sender.Address.ToString() + ": " + message);
        }

        private static void SetupTCPIPFromSD()
        {
            NetworkInterface ethernet1 = NetworkInterface.GetAllNetworkInterfaces()[0];
            if (ethernet1.IPAddress == "192.168.5.100")
            {
                //Setup Defaults as SD Card is not working currently...
                string LocalIPAddress = "10.201.1.99";
                string SubNetMask = "255.255.255.0";
                string Gateway = "10.201.1.254";

                if (File.Exists(@"IPData.txt"))
                {
                    using (FileStream filestream = new FileStream(@"IPData.txt", FileMode.Open))
                    {
                        StreamReader reader = new StreamReader(filestream);
                        Debug.Print(reader.ReadToEnd());
                        reader.Close();
                    }
                }
                ethernet1.EnableStaticIP(LocalIPAddress, SubNetMask, Gateway);
            }

            myIPAddress = IPAddress.Parse(ethernet1.IPAddress);
        }
    }
}

UDPReceiver.cs [Class]

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using EthernetSocketDefs;

namespace UDPMag_NetduinoPlus2
{
    public class UDPReceiver
    {
        public delegate void MessageReceived(string message, IPEndPoint sender);

        public event MessageReceived OnMessageReceived = null;


        private IPEndPoint localEndPoint = null;
        private IPEndPoint remoteEndPoint = null;
        public UDPReceiver(IPEndPoint ipeo)
        {
            this.localEndPoint = ipeo;

            // Create a delegate of type "ThreadStart", which is a pointer to the 
            // worker thread's main function
            ThreadStart delegateWorkerThread = new ThreadStart(Main);

            // Next create the actual thread, passing it the delegate to the main function
            Thread threadWorker = new Thread(delegateWorkerThread);

            // Now start the thread.
            threadWorker.Start();
        }

        #region The actual worker thread code
        /// <summary>
        /// This is a method which does the work of the worker thread.
        /// </summary>
        private void Main()
        {
            int bytes = 0;              // Holds number of bytes received
            byte[] rxBuff = null;       // Holds received message

            // Create a "UDP" socket.
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            // Bind the socket to the local endpoint and listen for incoming UDP datagrams.
            try
            {
                listener.Bind(localEndPoint);
            }
            catch (SocketException se)
            {
                SocketErrorCodes errorCode = (SocketErrorCodes)se.ErrorCode;

                switch (errorCode)
                {
                    case SocketErrorCodes.NetworkIsDown:
                        Debug.Print("Socket Exception on creation: NetworkIsDown");
                        break;
                    default:
                        Debug.Print("Socket Exception error: " + errorCode);
                        break;
                }
            }
            listener.ReceiveTimeout = 1000;
            
            // Loop forever
            while (true)
            {
                bytes = 0;
                string cause = "unknown";

                try
                {
                    //Debug.Print("Attempt to listen on " + localEndPoint.ToString());
                    if (listener.Available > 0)
                    {
                        rxBuff = new byte[listener.Available];
                        bytes = listener.Receive(rxBuff);
                    }
                    else
                    {
                        cause = "No Data Available";
                    }
                }
                catch (Exception ge)
                {
                    if (ge is SocketException)
                    {
                        SocketErrorCodes errorCode = (SocketErrorCodes)((SocketException)ge).ErrorCode;

                        switch (errorCode)
                        {
                            case SocketErrorCodes.NetworkIsDown:
                                // The network is not connected.
                                cause = "NetworkIsDown";
                                break;

                            case SocketErrorCodes.ConnectionTimedOut:
                                // Connection timed out - e.g. nothing received
                                cause = "ConnectionTimedOut";
                                break;

                            default:
                                Debug.Print("Socket Exception error: " + errorCode);
                                break;
                        }
                    } 
                    else 
                        cause = ge.Message;
                }

                if (bytes == 0)
                {
                    Debug.Print("Nothing received: reason - " + cause);
                }
                else
                {
                    // set the remote end point so we know who sent us the data.
                    remoteEndPoint = listener.RemoteEndPoint as IPEndPoint;

                    //Convert to string.
                    System.Text.UTF8Encoding e = new System.Text.UTF8Encoding();
                    string txtMessage = new string(e.GetChars(rxBuff));

                    // Call Event!
                    if (OnMessageReceived != null)
                        OnMessageReceived(txtMessage, remoteEndPoint);
                }
            }
        }

        private bool SocketConnected(Socket s)
        {
            return !(s.Poll(1000, SelectMode.SelectRead) & (s.Available == 0));
        }
        #endregion
    }
}



#3 berr08

berr08

    New Member

  • Members
  • Pip
  • 9 posts

Posted 07 August 2014 - 04:59 PM

To Update I have removed the Debug.print statments and changed a bunch of different things that seemed trivial (basically banging my head on the keyboard) and it started to continue to read after the first message.  Don't know why but it did...code is below incase anyone needs it.

 

At this point the only issue that remains is how to get the IP of the UDP message sender.  Any one know how to get that? It's not coming back in the Socket.RemoteEndPoint, so for testing I hard coded my IP to get the messages back....Pretty please? :D

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using Microsoft.SPOT;
using EthernetSocketDefs;

namespace UDPMag_NetduinoPlus2
{
    public class UDPReceiver
    {
        public delegate void MessageReceived(string message, IPEndPoint sender);

        public event MessageReceived OnMessageReceived = null;


        private IPEndPoint localEndPoint = null;
        private IPEndPoint remoteEndPoint = null;
        public UDPReceiver(IPEndPoint ipeo)
        {
            this.localEndPoint = ipeo;

            // Create a delegate of type "ThreadStart", which is a pointer to the 
            // worker thread's main function
            ThreadStart delegateWorkerThread = new ThreadStart(Main);

            // Next create the actual thread, passing it the delegate to the main function
            Thread threadWorker = new Thread(delegateWorkerThread);

            // Now start the thread.
            threadWorker.Start();
        }

        #region The actual worker thread code
        /// <summary>
        /// This is a method which does the work of the worker thread.
        /// It waits for a UDP message to be received and passes it using the 
        /// supplied Event.
        /// </summary>
        private void Main()
        {
            int bytes = 0;              // Holds number of bytes received
            byte[] rxBuff = null;       // Holds received message

            // Create a "UDP" socket.
            Socket listener = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);

            // Bind the socket to the local endpoint and listen for incoming UDP datagrams.
            try
            {
                listener.Bind(localEndPoint);
            }
            catch (SocketException se)
            {
                SocketErrorCodes errorCode = (SocketErrorCodes)se.ErrorCode;

                switch (errorCode)
                {
                    case SocketErrorCodes.NetworkIsDown:
                        Debug.Print("Socket Exception on creation: NetworkIsDown");
                        break;
                    default:
                        Debug.Print("Socket Exception error: " + errorCode);
                        break;
                }
            }
            listener.ReceiveTimeout = 1000;
            listener.Listen(16);
            
            // Loop forever
            while (true)
            {
                bytes = 0;
                rxBuff = new byte[4];
                string cause = "unknown";

                try
                {
                    //Debug.Print("Attempt to listen on " + localEndPoint.ToString());
                    if (listener.Available >= 4 && listener.Poll(1000, SelectMode.SelectRead))
                    {
                        bytes = listener.Receive(rxBuff, 4, SocketFlags.None);
                    }
                    else
                    {
                        cause = "No Data Available";
                    }
                }
                catch (Exception ge)
                {
                    if (ge is SocketException)
                    {
                        SocketErrorCodes errorCode = (SocketErrorCodes)((SocketException)ge).ErrorCode;

                        switch (errorCode)
                        {
                            case SocketErrorCodes.NetworkIsDown:
                                // The network is not connected.
                                cause = "NetworkIsDown";
                                break;

                            case SocketErrorCodes.ConnectionTimedOut:
                                // Connection timed out - e.g. nothing received
                                cause = "ConnectionTimedOut";
                                break;

                            default:
                                Debug.Print("Socket Exception error: " + errorCode);
                                break;
                        }
                    } 
                    else 
                        cause = ge.Message;
                }

                if (bytes == 0)
                {
                    //Debug.Print("Nothing received: reason - " + cause);
                }
                else
                {
                    // set the remote end point so we know who sent us the data.
                    remoteEndPoint = new IPEndPoint(IPAddress.Parse("10.201.1.24"), 8888);//listener.RemoteEndPoint as IPEndPoint;

                    //Convert to string.
                    System.Text.UTF8Encoding e = new System.Text.UTF8Encoding();
                    string txtMessage = new string(e.GetChars(rxBuff));

                    // Call Event!
                    if (OnMessageReceived != null)
                        OnMessageReceived(txtMessage, remoteEndPoint);


                }
            }
        }
        #endregion
    }
}



#4 jrlyman3

jrlyman3

    Advanced Member

  • Members
  • PipPipPip
  • 67 posts
  • LocationNorth St Paul. MN

Posted 11 August 2014 - 02:31 AM

I took a quick look and I think that you're missing:

        

IPEndPoint localEndPoint = new IPEndPoint(IPAddress.Any, port);

 

before listener.Bind(localEndPoint);

 

Also, you should use listener.RecieveFrom() which will receive the data and tell you who it came from.  This works best with UDP since you can receive data from multiple hosts on the same socket (no connection).

 

John



#5 berr08

berr08

    New Member

  • Members
  • Pip
  • 9 posts

Posted 11 August 2014 - 01:36 PM

Interesting, I will give this a shot, thanks for the feedback!







0 user(s) are reading this topic

0 members, 0 guests, 0 anonymous users

home    hardware    projects    downloads    community    where to buy    contact Copyright © 2016 Wilderness Labs Inc.  |  Legal   |   CC BY-SA
This webpage is licensed under a Creative Commons Attribution-ShareAlike License.