c#, socket cannot receive fragmented UDP packets - c#

I have an embedded device which is connected to my PC directly through ethernet.
The device is streaming audio to pc through UDP and it sends 4096 bytes UDP packet.
Given that, the MTU for ethernet is 1500 bytes the packet will be fragmented.
At PC I have a c# program that tries to receive packets and decode it. UDP receiver can receive packets very well when they have under 1500 bytes payload but it cannot receive fragmented packets.
I've monitored incoming packet by Wireshark and I can see that there is not any failure in packets nor discarded.
I don't know the problem is in my code or C# socket is Unable to receive these kinds of packets. in both cases what would be the solution?
1st Attempt: (usinfg Socket)
Socket sokcet = new Socket(SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ep = new IPEndPoint(IPAddress.Any,5222);
sokcet.Bind(ep);
int counter = 0;
while (true)
{
if(sokcet.Available > 0){
byte[] bytes = new byte[sokcet.Available];
int receivedBytes = sokcet.Receive(bytes);
string print = String.Format("Packet Received : {0},{1}", receivedBytes, counter);
Console.WriteLine(print);
}
}
2nd Attempt: (using UDPClient)
IPEndPoint groupEP = new IPEndPoint(IPAddress.Any, listenPort);
UdpClient listener = new UdpClient(listenPort,AddressFamily.InterNetwork);
while (!done)
{
byte[] bytes = listener.Receive(ref groupEP);
}
None of them are working for packets larger than 1500 bytes.
Update 1:
I tested the scenario in Loopback(127.0.0.1) and I can receive 4k UDP message very well.
Update 2:
#Evk I tested the scenario from another pc connected to mine over a Switch and also over a router. now I am sure that C# does not have any problem. not sure about OS (win7 ultimate 64x).
My embedded device uses LWIP and there are some reports of a similar situation that happened when users used LWIP for sending large UDP packets. but I'm not sure this is my case.
I even checked UDP packet's Source and Destination address, Checksum and ... and I can't figure out why OS dropping my packets. is there any tools that can analyze network packet to tell if they have any problem?

I would make certain that the messages are in fact, being delivered to your processes' UDP receive queue. You may see it wireshark, but that is not a guarantee that it did not later get dropped or filtered at the UDP protocol level.
I would open a command window (CMD) and run this in a loop as you send your traffic and run your decoding application (Also, stop other applications that may use UDP as they may interfere with these figures):
> netstat -s -p udp
UDP Statistics for IPv4
Datagrams Received = 48775 <======= [This *should* increase]
No Ports = 83823
Receive Errors = 16367 <====== [ WATCH THIS]
Datagrams Sent = 130194
If you notice receive errors going up while your application sits there and does not seem to processing...then there is chance that the > 1500 byte packets are getting dropped by UDP for some reason. You may need to either increase your application's socket receive buffers or look for windows UDP network configuration options that would cause > MTU packets to be dropped on receive..

Related

Multible programs/instances using the same UDP Port in C#

I am struggling with a bit of network magic and hoped someone would be able to explain me what is happening.
I am trying to reuse udp ports. So if I have multible programs listening on the same udp port i want both of the applications to receive the data send by a different device.
Using the following code I'am able to achive just that:
IPEndPoint localEndoint = new IPEndPoint(IPAddress.Any, 67); //the local endpoint used to listen to port 67
//Create a new UDP Client and bind it to port 67
DhcpSniffer = new UdpClient();
DhcpSniffer.ExclusiveAddressUse = false; //Allow multible clients to connect to the same socket
DhcpSniffer.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); // Connect even if socket/port is in use
DhcpSniffer.Client.Bind(localEndoint);
DhcpSniffer.Client.ReceiveTimeout = Timeout;
//receive on port 67
dhcpPacket = DhcpSniffer.Receive(ref localEndoint);
Both of my programs can listen to DHCP messages in the network and don't block each other.
Now i want to do the same thing with port 15120 where a RTP video stream is streamed to. However this does not work. I am using the same code but with no success only one application at a time can receive the stream, the other will run in a timeout.
IPEndPoint RemoteIpEndPoint = new IPEndPoint(IPAddress.Any, port);
//Create a new UDP Client and bind it to port 15120
udpReceiver = new UdpClient();
udpReceiver.ExclusiveAddressUse = false; //this is an attempt to receive the stream on mutlible instances...this works for DHCP but not for RTP for some reason....
udpReceiver.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true); // Connect even if socket/port is in use
udpReceiver.Client.ReceiveTimeout = timeout; //set the sockete timeout
udpReceiver.Client.Bind(RemoteIpEndPoint); //bind to the port from any IP
//receive packets on port 15120
Byte[] receiveBytes = udpReceiver.Receive(ref RemoteIpEndPoint);
I hope somebody is able to shine a light on my confusion
Update:
I found out it works with DHCP because it is send to the broadcast IP (255.255.255.255). Now I need to find out how i can change the Socket behaviour to treat my RTP stream as if it was broadcasted so i can see it in two application at the same time. (Yes I could configure my stream-source to broadcast, but this is not the goal of this).
The goal is to reconfigure the Socket to behave as explained. Not to save the stream on a harddrive or redirect it using the local host.
First, its not possible to have multiple programs listen on the same port (As far as I know it's a big security conflict)
What you can do tough, is use a NetworkManager that listen on you port (Lets call it port 8080) who will then redirect the information to you apps ports (App1 could use port 8081 and App2 use port 8082). Either you write your own, using Flask to listen on 8080 and then rerouting the package to localhost:8081 and localhost:8082 could be a simple and fast solution.
Doing this would help you secure the network and you can redirect to as many ports as you need, pretty much like a docker swarm would balance the incoming network to its cluster.
It is not possible with multible programs to access the data from a unicast UDP package, it works only with multicast, there is no "easy" way around this by reconfiguring the UdpClient

c# Mono App in Linux/Raspbian can't read from serial port while a socket is being served (can write / but the serial input buffer reports 0 bytes)

I have a c# mono application to be mounted on Linux/raspbian (raspberry pi 3 model b+) , that application access the serial port in order to communicate with an special device (wiegand card reader) to get information about the reading status and get the information on the card. All the serial communication is going fine except by:
This application also needs to act as SERVER in order that other computers can request information about the serial-device. My trouble is that when the application is serving a socket request its block the serial input buffer (although i can write to serial port) i can't read the input buffer because it always reports 0 bytes (during the socket operation is alive), when the socket operations ends the serial input (response from the weigand interface) is queued again into the input buffer, That to late because the socket operation has ended and i need to return the serial-data in the socket result.
If i made the socket request from the same machine acting as server (server and client on the same raspberry pi) all of this works fine and I'm able to read the serial port during the socket operation, the trouble is when the socket request is coming from another machine in the network.
I don't know the reason about this behavior, because i can write to the serial port while a socket request is being server, but i can't read the serial port (because it is reporting 0 bytes) while the socket operation is in progress.. the serial information is being posted to the input buffer until the socket operations ends.
Can you give any lights to fix this trouble ?? maybe i need to configure something on the Linux system, or maybe this could be a bug in mono ??
Can you advice on this or make suggestions in order to improve the process, i need to return in the socket operation the results of reading the serial port.
Thanks

how to check a remote udp port

I want to check the connection to a remote machine using UDPClient. Heard that it will return an icmp packet if failure occurs. How we can catch it?
How it is possible to check for a remote machine?
UdpClient receivingUdpClient = new UdpClient();
receivingUdpClient.Connect(IPAddress.Parse("10.2.2.13"), 80);
Byte[] sendBytes = Encoding.ASCII.GetBytes("0");
Var b=receivingUdpClient.Send(sendBytes, sendBytes.Length);
With UDP, there is no definite way of knowing whether the packet reached its destination or not (compare with TCP, which sends ack packets to let the sender know its packet was received).
It is true that in some cases, ICMP packets are sent, but what if the packet was filtered out (or simply dropped) somewhere along the routing path? As far as I have seen, most home routers are pre-configured to drop all ICMP on external ports, for example.
Instead of relying on ICMP packets, you could investigate if the protocol you are using has a PING packet (or some equivalent no-op packet, or if you created the protocol -- add it!) and use that with a timeout/retry logic to verify if the service is available.

C# console app won't send UDP multicast packet on Windows Server 2003

I can't seem to get my little test app to send a UDP multicast packet on a particular machine running Windows Server 2003. I have it setup to send a packet to Google's public DNS and another to 239.192.250.250. It runs fine without throwing any errors. But in the Wireshark output, only the Google packet shows up. Any ideas?
static void Main(string[] args)
{
var socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
var data = ASCIIEncoding.UTF8.GetBytes("hello world");
socket.SendTo(data, new IPEndPoint(IPAddress.Parse("8.8.8.8"), 80));
socket.SendTo(data, new IPEndPoint(IPAddress.Parse("239.192.250.250"), 80));
Console.ReadKey();
}
And here's the Wireshark output:
No. Time Source Destination Protocol Length Info
205 1.83925300 ********** 8.8.8.8 UDP 53 Source port: 62432 Destination port: http
On every other machine I've tested including a Windows 2008 R2 server, I get something to the effect of:
No. Time Source Destination Protocol Length Info
58 4.52926800 ********** 8.8.8.8 UDP 53 Source port: 56530 Destination port: http
60 4.52940400 ********** 239.192.250.250 UDP 53 Source port: 56530 Destination port: http
If you are on a Network switch, they only routes the packet to the connection of the destination machine. Whereas an unswitched hub broadcast packets to all ports.
Wireshark does packet sniffing therefore it cannot see all packets on a switched router.
Here is excerpt from Switch Reference # Wireshark:
As noted in the Wireshark FAQ, capturing in a switched network environment can prove to be challenging. An individual switch port will receive broadcast, multicast, and unicast traffic destined for that particular port. In most cases it won't receive unicast traffic for other ports, which is what you're probably trying to capture.

C# - WireShark detects incomming packets but application does not receive them

I've got a strange problem. I have a client sending packets to my server, but my servers UDP socket never receives them. Same thing happens the other way around, if I send and he tries to receive.
Check this image, captured from wireshark:
http://img263.imageshack.us/img263/2636/bokus.png
I hav bound my UDP socket to EndPoint 192.168.2.3, which is the internal IP of the server, and port 9998.
The client sends data to my IP, which should then be forwarded to the local server machine..
As you can see wireshark clearly detects incomming packets for 192.168.2.3 with destination port 9998 but nothing gets delivered!
(...why does it say distinct32 btw in destination port?)
Something else to watch for is make sure any firewall you might running has a rule setup to allow communications on your port 9998.
If I had to guess (would need to see your recieving C# code to know), It looks like you might be trying to receive UDP packets but using TCP protocol on the client side. (Or i might just be misunderstanding some of the text of your screenshot.)
Theres no need to 'listen' for a connection when using UDP. UDP packets don't have a connect/disconnect protocol. Nor do they guarantee that packets are received in the same order they're sent.
try using something along these lines in your C# client and see if you get data.
var udpClient = new System.Net.Sockets.UdpClient(9998);
Byte[] receiveBytes = udpClient.Receive(ref RemoteIpEndPoint);

Categories