Troubleshooting UDP Code - c#

I'm working on a system to send data between peers on a network. One app is written in Java for the Android. The other app is written in C# on the PC.
I wrote code in Java on the Android to send UDP datagrams. And I wrote C# code to both send and receive datagrams. I tried to send messages from Android to PC. I could see the message in WireShark but not in my program. So, I put my program on a second PC. I succeeded in sending a message from my PC to the second one. But when I tried to send a message from seond PC back to mine it failed. I could see it in WireShark on my PC but not my application. Im at a loss for what to try next. Do you have any suggestions? Why would the UDP packet be visible in WireShark but not my application?
Here is my code.
//C# code on PC
//Sender
sending_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, rotocolType.Udp);
send_to_address = IPAddress.Parse(strIPAddress);
sending_end_point = new IPEndPoint(send_to_address, intPort);
sending_socket.EnableBroadcast = true;
byte[] bytMessage = Encoding.ASCII.GetBytes(strMessage);
sending_socket.SendTo(bytMessage, sending_end_point);
//Listener
UdpClient listener = new UdpClient(listenPort);
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
byte[] bytReceiveDataByteArray;
try
{
listener.EnableBroadcast = true;
while (isRunning)
{
//listen for data from sender
bytReceiveDataByteArray = listener.Receive(ref groupEP);
//Fire an event to send the data to the hosting code
if (DataReceived != null)
{
DataReceivedEventArgs e = new DataReceivedEventArgs(bytReceiveDataByteArray);
DataReceived(this, e);
}
}
}
//Java code on Android
DatagramSocket socket = new DatagramSocket();
InetAddress serverIP = InetAddress.getByName(strIpAddress);
byte[] outData = (strMsg).getBytes();
DatagramPacket out = new DatagramPacket(outData,outData.length, serverIP,50005);
socket.send(out);
socket.close();
Thanks,
Mike

If I understand the problem correct when your program runs on a specific PC (lets call it "Windows1") it never receives the UDP packets. It will not receive them from Java Android or from C# code running on a different PC ( lets call it "Windows2").
However when you run your program on "Windows2" it DOES receive messages from "Windows1". Sounds like you have the firewall enabled on "Windows1" and do not have an exception for UDP port 50005. On "Windows2" your firewall is turned off or has the exception for 50005 and this is why it receives messages from "Windows1".
Note that since UDP is not connection oriented, firewall errors will not cause the usual connection timed out error. The messages are just dropped and you never get an error.

Related

udpclient receives broadcast only locally (c#, Unity)

I want to receive a UDP message which was broadcasted to 255.255.255.255 with a UdpClient within Unity.
But whatever combination of settings I try, it only receives a message, if it was sent from localhost.
I have tried fitted example code from these resources, non worked:
https://gist.github.com/michaelosthege/857acac92b8ee689a6bb30d5bf23d9f6
C# UDP Broadcast and receive example
UdpClient receive on broadcast address
How to do Network discovery using UDP broadcast
I'm running the Code below a task.
private void Listen()
{
udpClient = new UdpClient(9000);
//udpClient.Client.Bind(new IPEndPoint(IPAddress.Any, 9000));
//udpClient.EnableBroadcast = true;
//udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
//udpClient.ExclusiveAddressUse = false;
//broadcastAddress = new IPEndPoint(IPAddress.Any, 9000);
//udpClient.Client.Bind(broadcastAddress);
//udpClient.Connect(broadcastAddress);
//var from = new IPEndPoint(IPAddress.Any, 9000);
var from = new IPEndPoint(0, 0);
while (true)
{
var receive = udpClient.Receive(ref from);
var msg = Encoding.UTF8.GetString(receive);
Debug.Log($"Received message \"{msg}\"");
Debug.Log($"from {from} ({from.Address})");
}
}
I have used several of the commented lines in combination.
When I send something from within the same Application to 255.255.255.255 with another UdpClient on port 9000, it works as expected.
When I send something from any other machine on the network to 255.255.255.255
any machine in the network receives it (checking with PacketSender on osx devices)
On the windows machine I'm developing this application on, the message is received by UdpSenderReceiver
But the udpClient from within Unity does not receive anything - and the Firewall does not ask or tell me anything.
What could be the issue here?
Apparently Windows Defender by default blocks the Unity Editor (but not UdpSenderReceiver).
I had to resolve it by Admitting the Unity Editor on the public domain
The Rules for
Unity 2019.3.3f1 Editor
Unity 2019.3.4f1 Editor
had been present and were not modified.
I modified the Rule for Unity 2019.2.4f1 Editor in order to allow access from the public domain (I simply allowed all domains).

Sending UDP messages works, receiving not - C# on Unity3d

Hello,
I am trying to set up a UDP connection in Unity3d and it has been giving me some headace the past days:
The Unity script I am running is supposed to receive and maybe in the future send UDP messages.
Next to Unity I am using Wireshark to track the packets and PacketSender to generate and receive UDP messages.
The source of the messages is a PLC which sends a package every second, containing two floats (8 bytes) for testing.
The PLC IP is 192.168.0.1 and it is connected directly via Ethernet to the Laptop running Unity. (no switch, no router)
My Ethernet Port has the IP 192.168.0.41, and the messages are coming in via Port 8052.
What I can see in Wireshark via :
Packages arriving from the PLC to Unity
Packages leaving from Unity to the PLC
The packages have the expected structure
What I can see / do in PacketSender:
packages arriving from the PLC (via Port 8052)
send messages to the PLC that are visible in Wireshark
by receiving the packages here it should also be safe to say that the firewall port window works.
I can NOT receive packages with PacketSender if I already started my Unity-receive script...
... which should be an indicator, that the Unity UDP socket is up and running, hopefully swallowing messages.
If I call netstat -aon I can see the Unity UPD Process at the expected Port & IP;
0.0.0.0:8052 or 192.168.0.41:8052, depending on how it is created. Also I can see that no other process is using the same port.
But what does not work is to actually receive and use the data in my Unity script.
What works is to receive data send via the local IP 127.0.0.1 from another Unity script.
By now I have tried several ways to create a socket:
var udpClient = new UdpClient(8052,AddressFamily.InterNetwork)
var udpClient = new UdpClient(8052)
UdpClient udpClient = new UdpClient(8052,AddressFamily.InterNetwork)
var udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
I have tried...
...to receive the messages sychronous or asychronous
...to run the receive-loop in the Main thread or in a background thread
...to en-/disable blocking of the client
...to bind the client to an IP or leave it on IPAddress.Any
...to shut down the HyperV switch I had on the Ethernet Port (still shut down)
...to open the relevant ports in the firewall
...to restart the laptop
...about every solution I could find in any forum.
It feels like either the C# socket and the Step7 socket speak a different UDP or the C# socket is not functioning on the receiving side as expected.
The package is really at the doorstep of the socket and it ignores it.
Setup specs:
PLC: CPU315-2 PN/DP
Laptop: Dell Latitude, i5, 8GB RAM, Win10 Enterprise, 64-bit
Unity: Unity 2017.3.1f1, Only asset is PlayMaker
Current test code:
using System;
using System.Net;
using System.Net.Sockets;
using UnityEngine;
using System.Threading;
public class UDPReceive03 : MonoBehaviour
{
Thread receiveThread;
public UdpClient socket;
private bool canReceive;
public static bool messageReceived;
public String statusThread;
public int UDP_LISTEN_PORT;
private int alive;
// Use this for initialization
void Start()
{
UDP_LISTEN_PORT = 8052;
print("started");
canReceive = true;
messageReceived = false;
alive = 0;
receiveThread = new Thread(new ThreadStart(ReceiveData));
receiveThread.IsBackground = true;
receiveThread.Start();
}
// Update is called once per frame
void Update()
{
// I know the code below is ugly, but that was my rebellion agains the situation
statusThread = (canReceive) ? "Waiting" : "Busy";
if (alive % 180 == 0)
sendResponse(1);
alive = (alive<180) ? alive + 1 : 1;
}
private void ReceiveData()
{
using (var udpClient = new UdpClient(8052,AddressFamily.InterNetwork))
{
int loggingEvent = 0;
while (true)
{
print("started to receive");
IPEndPoint remoteEndPoint = new IPEndPoint(IPAddress.Any, 0);
var receivedResults = udpClient.Receive(ref remoteEndPoint);
loggingEvent += receivedResults.Length;
print("Success, received " + loggingEvent.ToString() + " bytes.");
sendResponse(loggingEvent);
}
}
}
private void sendResponse(int count)
{
socket = new UdpClient(8051);
// sending data
IPEndPoint target = new IPEndPoint(IPAddress.Parse("192.168.0.1"), 2000);
// send a couple of sample messages:
for (int num = 1; num <= count; num++)
{
byte[] message = new byte[num];
socket.Send(message, message.Length, target);
}
socket.Close();
}
}
I am aware of the lack of comments in the code, but as you might have guessed, the code changed a lot lately.
Thank you for the help.
If you want to receive from external source you need to allow Unity on firewall or disable firewall. Firewall blocks unity editor connection with external source, that is why you can send data but can not receive. If you build your project, your code will work, because it will ask you on first running
So after a very frustrating journey I found a work-around that is not nice but does the job:
I wrote a python script that opens a socket, receives the external data and forwards it via the local IP to Unity. And that works.
Here is the code:
# Import libraies
import socket
import time
# Set send IP adress and port
UDP_IP = "127.0.0.1"
UDP_PORT_Rec = 8052
UDP_PORT_Unity = 8055
print("Receiving on Port:" + str(UDP_PORT_Rec))
print("Sending to IP:" + UDP_IP + ":" + str(UDP_PORT_Unity))
# Set socket to send udp messages and bind port
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
sock.bind(('',UDP_PORT_Rec));
## Keep sending message from file location
while True:
data, addr = sock.recvfrom(1024) #buffer size, hopefully no problem if too big
print("Received")
sock.sendto(data, (UDP_IP, UDP_PORT_Unity))
print("Send")
Tools that are useful for your trouble shooting:
Install Wireshark! It is probably the best tool out there to track Internet traffic. Packages that are visible in Wireshark might not be visible for a normal application!
Use Packet Sender to generate and receive traffic. The application uses a basic approach to receive packages - If it can then your programm should be able to as well.
Check with netstat -aon if your socket is running.
For completion: Check your firewall settings.

C# - UDP SocketException - Conflict between applications

I'm building a dashboard like website for a formula 1 game.
I followed this guide. (Section : Enabling the UDP Telemetry Output)
Basically, the game sends packets on 127.0.0.1:20777 using UDP, and I'm trying to receive these packets in my app.
My problem is that there seems to be some sort of conflict between the game and my app when I try to receive the packets. For instance, if I compile the app when the game is not running, it compiles just fine, but of course, I do not receive any data.
Once the game is started, I cannot compile, and get a SocketException that says "Only one usage of each socket address (protocol/network address/port) is normally permitted".
I tried the following :
UdpClient client = new UdpClient(20777);
and
UdpClient client = new UdpClient();
IpEndPoint ip = new IpEndPoint(IpAdress.Any, 20777);
client.Connect(ip);
The first solution throws "Only one usage...", and the second solution throws "The requested address is not valid in its context". I am very new to UDP, so I don't really know what am I doing wrong or how to fix it.
Thanks !
i believe you should be trying to listen on the port 20777 rather than trying to connect.
May be something like this:
var client = new UdpClient();
IPEndPoint ep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 20777 ); // endpoint where server is listening
client.Connect(ep);
// then receive data
var receivedData = client.Receive(ref ep);
Console.Write("receive data from " + ep.ToString());
Console.Read();

Sending UDP Messages to IPAddress.Broadcast fails with SocketError 10065 (WSAEHOSTUNREACH)

Our C# applications targeting .NET 4.0 sends an udp broadcast from time to time to IPAddress.Broadcast. We recently received a log (run on Win 8.1 Pro), which shows up that sending to 255.255.255.255:somePort resulted in a SocketException with ErrorCode 10065 (WSAEHOSTUNREACH).
I'd consider this as non remarkable, if either the network connection is lost or if sending to a specific machine. But at the time of the exception, the network was up and running, even incoming UDP packages could be read from the same socket.
Here's the code being used:
public void Setup(){
_incoming = new IPEndPoint(IPAddress.Any, IncomingPort);
_outgoing = new IPEndPoint(IPAddress.Broadcast, OutgoingPort);
_udpClient = new UdpClient();
_udpClient.Client.ExclusiveAddressUse = false;
_udpClient.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
_udpClient.Client.Bind(_incoming);
}
public void Send(byte[] dataToSend)
{
_udpClient.Send(dataToSend, dataToSend.Length, _outgoing);
}
Now the two questions regarding this issue:
1.) What could cause this behavior?
2.) What scenario do i need to setup to, in order to be able to test the same behavior?

Can't Receive UDP Windows RT

I'm writing a Windows Store/Metro/Modern/RT app for Windows 8/RT that needs to receive UDP packets on port 49030, but I can't seem to receive any packets. I've followed the tutorial on using DatagramSocket to the letter, and I'm getting nothing. I know my sender program is sending data, as I can see it on wireshark. I also wrote a test C# console app that uses the regular BSD socket API (System.Net.Sockets.Socket) that properly receives the data over UDP.
This is the code that works:
Socket s = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
s.Bind(new IPEndPoint(IPAddress.Any, 49030));
byte[] buf = new byte[5000];
while (true)
{
Console.WriteLine("Received " + s.Receive(buf) + " bytes.");
}
This outputs lines that report the number of bytes that are being sent, like expected.
My code for the RT app:
public async void StartListening()
{
DatagramSocket s = new DatagramSocket();
s.MessageReceived += s_MessageReceived;
await s.BindServiceNameAsync(this._port.ToString());
}
void s_MessageReceived(DatagramSocket sender, DatagramSocketMessageReceivedEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Hark! A packet!"); // Breakpoint here
}
After calling StartListening(), the breakpoint is never hit, and nothing is printed to the output log.
I tried running the DatagramSocket sample offered by MSFT, and it worked no problem (of course). I can see that the socket is getting opened/listened on, because it shows up in resmon.exe. I also have all of the proper capabilities enabled in the manifest for the app. I've tested it on my x86 laptop and on my Surface RT (remote debugging), and they both exhibit the same behavior.
Any ideas as to why it isn't working?

Categories

Resources