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!