I want to check if data is avaiable on the UDP multicast address, the only mechanism I found was the Poll method.
Setup:
client = new UdpClient(localEp);
client.JoinMulticastGroup(multicastAddr, localIpAddress);
client.Connect(multicastAddr, receiveport);
Polling:
if (!client.Client.Poll(100, SelectMode.SelectRead))
The client is connected (I checked) but never returns true.
In wireshark I can see the udp datagrams are sent correctly.
Suggestions for fixes?
Edit:
IPEndpoint localEp = local ipv4 unicast address, port for multicast udps
receiveport = port for receiving multicasts
multicastaddr = IPAddress
Connecting UDP socket means restricting datagram source address and port to the specified pair when receiving, and setting default destination address and port when sending.
Remove call to Connect().
Edit 0:
You need to bind to the multicast address, not the local IP. Either remove localEp from the constructor, or replace it with pair of the multicast group/port. See examples on MSDN.
And you are wrong, you can Receive() just one datagram.
Related
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
I have two network interfaces. I take 192.168.1.100 from eth0 and 192.168.1.227 from eth0. Which nic does my tcp listener listen when i use the code below:
tcpListener = new TcpListener(IPAddress.Any, 1234);
tcpListener.Start();
Gateway and subnet mask configurations are different for each nic also.
new TcpListener(IPAddress.Any, 1234) initializes a new listener that listens for incoming connection attempts on the specified local IP address and port 1234.
In your case represents IPAddress.Any all local IP addresses.
I hope this will answer your question.
You can find more information here: http://msdn.microsoft.com/library/vstudio/system.net.sockets.tcplistener
It's binding to all IP addresses on your computer, not necessarily all NICs, as this will also bind to local loopback, along with any virtual adapters you may have.
i am sending data to UDP socket using this code
Socket udpClient = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Parse(obj.destAddress), obj.destPort);
byte[] buf = new byte[obj.length];
Array.Copy((byte[])obj.data, buf, obj.length);
int n = udpClient.SendTo(buf, ipEndPoint);
udpClient.Close();
this code works fine when IP exists in current network, but it takes 3-5 seconds when I send data to unknown IP address. This causes main application to hang for 3-5 seconds.. What could be the reason behind this problem..
Your IP stack cannot send a UDP packet until it the MAC address is known. The is done with the ARP protocol. The IP stack sends an ARP query and times out waiting for the ARP response. When finished the SendTo returns.
When you send a UDP packet to the internet the MAC address of the gateway is necessary. Since the gateway is usually available the timeout does not appear since your IP stack was able to send to the gateway indenpendent of if the destination is available or not.
You can try to set a socket option to operate asynchronously.
How can i specify specific ipaddress:port for udpclient to receive? im confused with updclient.client.localendpoint and udpclient.client.remoteendpoint. i was thinking maybe its remoteendpoint, but i cannot display remoteendpoint value. plus my local endpoint ip is 0.0.0.0. what is that mean?
0.0.0.0 means "any address". The local endpoint is the IP address and port you will listen for packets on. The remote endpoint is not required for UdpClient objects. It only specifies the default host to send a packet to, if you do not specify one when sending the packet.
You can leave the local endpoint as 0.0.0.0 if you want to listen for traffic on all of your assigned IP addresses on all of your network connections. You only need to change this if you only want to listen on one particular address/connection.
How to find out Connected Clients Ip Address. And how we can store that address to an array of datatype IPAddress?
Check the RemoteEndPoint of your socket:
If you are using a connection-oriented
protocol, the RemoteEndPoint property
gets the EndPoint that contains the
remote IP address and port number to
which the Socket is connected. If you
are using a connectionless protocol,
RemoteEndPoint contains the default
remote IP address and port number with
which the Socket will communicate. You
must cast this EndPoint to an
IPEndPoint before retrieving any
information. You can then call the
IPEndPoint.Address method to retrieve
the remote IPAddress, and the
IPEndPoint.Port method to retrieve the
remote port number.
If you use higher level components like TcpListener and TcpClient then you can access the underlying socket and retrieve the remote end point.
If you use other technologies like ASP.Net, WCF or Remoting then you must say so in your post.
To store an IPAddress you retrieve the underlying bytes using IPAddress.GetAddressBytes. You reconstruct the address from the bytes using the byte[] constructor.
Are we in Windows? Do you need to use this information inside an application or a console command could do the trick?
maybe you could try with netstat -na in a shell.