Send a UDP message to another network using socket - c#

I've been making a sample program wherein the user can broadcast messages using sockets and UDP connection. It was successful in LAN but I can't broadcast my messages to other networks (e.g. 10.15.1.11's message to 10.11.1.23). Here's my sample code:
Listener:
bworker = sender as BackgroundWorker;
Socket _ListenerSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
IPEndPoint _ListenerEndPoint = new IPEndPoint(IPAddress.Any, _port);
_ListenerSocket.EnableBroadcast = true;
_ListenerSocket.Bind(_ListenerEndPoint);
//_ListenerSocket.Connect(MulticastIP, _port);
_ListenerSocket.Ttl = 255;
_ListenerSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(MulticastIP));
while (true)
{
byte[] msg = new byte[1024];
_ListenerSocket.Receive(msg);
string StringData = Encoding.Unicode.GetString(msg);
bworker.ReportProgress(0, StringData);
}
Sender:
Socket _ClientSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_ClientSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.AddMembership, new MulticastOption(MulticastIP));
_ClientSocket.SetSocketOption(SocketOptionLevel.IP, SocketOptionName.MulticastTimeToLive, int.Parse(ttl));
IPEndPoint _ClientEndPoint = new IPEndPoint(MulticastIP, _port);
_ClientSocket.Connect(_ClientEndPoint);
byte[] MsgByte = new byte[1024];
MsgByte = Encoding.Unicode.GetBytes(txtmsg.Text);
_ClientSocket.Send(MsgByte);
Variables:
public const int _port = 8041;
public const string ttl = "255";
public IPAddress MulticastIP = IPAddress.Parse("239.0.0.222");
Thanks.

The router between you and the other LAN probably refuses to forward packets with multicast destination IPs. To handle multicast properly, the router itself has to be multicast-aware and implement protocols such as PIM (for coordinating multicast between routers) and IGMP (for coordinating multicast with end-hosts)

Your router probably doesn't forward multicast packages. In order for multicast to work all routers along the path of communication must me multicast enabled. Ping only requires the router to forward ping packages so that will really only tell you if you can reach the other computer at all. Take a look at this article to learn more about multicasting in C#.

Related

Receive IP-address of sender

I have a computer connected to two readers through TCP/IP, using UDP protocol.
My code looks like this:
IPEndPoint Info = new IPEndPoint(IPAddress.Any, MVM.readerProperties.AutoPort);
EpcSocket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
EpcSocket.Bind(Info);
IsConnected = true;
EpcSocket.BeginReceive(Epcrecebuffer, 0, Epcrecebuffer.Length, SocketFlags.None, new AsyncCallback(EpcReceiveCallBack), null);
My question is how can I find what IPAdress teh sender has? I need that in my Async function Epcreceivecallback? When using this code the LocalEndpoint is said to be 0.0.0.0
When using one reader I have no issue then I know it's from that one. But when I have two I would like to know from which one the data comes.

UDP socket listener not receiving data

My local ip is : 192.168.0.70,
External ip is : 192.168.0.50 : 60000
I want receive data from external ip sending to local ip. I use Socket class because i can send data using remote IPEndPoint. But when Udp connection closed, local ip's port dynamically changing. How can i receive data?
private static void UdpConnect()
{
try
{
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("192.168.0.50"), 60000);
Socket client = new Socket(AddressFamily.InterNetwork,
SocketType.Dgram, ProtocolType.Udp);
client.Connect(remoteEP);
byte[] sendbuffer = { 1, 2, 3 };
client.Send(sendbuffer);
byte[] receivebuffer = new byte[512];
client.Receive(receivebuffer);
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
If you need to listen on a specific local port, use Socket.Bind and then Socket.ReceiveFrom.
You don't need the Socket.Connect call since UDP is a connectionless protocol.

C# UDP socket app to listen to messages from various sockets

I have a system monitor app that needs to listen to messages from various UDP sockets on another machine. The other sockets continuously send heartbeats to this given IP/port.
This exception gets thrown when calling BeginReceiveFrom:
"A request to send or receive data was disallowed because the socket is not connected and (when sending on a datagram socket using a sendto call) no address was supplied"
I shouldn't have to call connect because data is already getting sent to this ip endpoint. plus the data is coming from various sockets.
private Socket m_socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
private void Window_Loaded(object sender, RoutedEventArgs e)
{
// bind socket
// Establish the local endpoint for the socket.
// Dns.GetHostName returns the name of the
// host running the application.
IPHostEntry ipHostInfo = Dns.Resolve(Dns.GetHostName());
IPAddress ipAddress = ipHostInfo.AddressList[0];
m_localEndPoint = new IPEndPoint(ipAddress, 19018);
m_socket.Bind(m_localEndPoint);
m_socket.BeginReceiveFrom(m_data,
m_nBytes,
MAX_READ_SIZE,
SocketFlags.None,
ref m_localEndPoint,
new AsyncCallback(OnReceive),
null);
}
private void OnReceive(IAsyncResult ar)
{
int nRead = m_socket.EndReceiveFrom(ar, ref m_localEndPoint);
}
I was able to get the desired behavior with the UdpClient class.
Your problem was you were binding to the IP assigned to you, you should bind to IP you want receive from - in your case:
m_socket.Bind(new IPEndPoint(IPAddress.Any, 12345));

Sending data over UDP to a destination with multiple clients open

I am currently using this function to send data from the server to the clients
private static void send_message(string ip, string message)
{
byte[] packetData = System.Text.UTF8Encoding.UTF8.GetBytes(message);
int port = 11000;
IPEndPoint ep = new IPEndPoint(IPAddress.Parse(ip), port);
Socket client = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
client.SendTo(packetData, ep);
}
But this would mean a destination IP/port can only have one client open to receive the data, because having two clients open would mean one client can retrieve data that was meant for another (if I'm correct).. how do I solve this?
Receiving function:
private static Int32 port = 11000;
private static UdpClient udpClient = new UdpClient(port);
public static void receive_threaded()
{
Thread t = new Thread(() =>
{
while (true)
{
IPEndPoint remoteIPEndPoint = new IPEndPoint(IPAddress.Any, port);
byte[] content = udpClient.Receive(ref remoteIPEndPoint);
if (content.Length > 0)
{
string message = Encoding.UTF8.GetString(content);
parseMessage(message);
}
}
});
t.Start();
}
1) You should implement some kind of protocol so that your server has a "well known" port to accept connections. Use this port to inform your client ANOTHER port where the client must connect. Use a different port for each client.
Your client conects to the server at 11000. Your server assigns a unique port for the client, let's say 11001 for the firts client. Then the server opens a connection at 11001. The client closes connection at 11000 and opens a new connection at 11001 to receive the data.
2) Why UDP?
I don't see why you need to open a new socket at all. You already have each client's address and port, from the first packet they sent you. Just send a packet to that address:port. I absolutely don't get the other suggestion of setting up extra ports either.

How to specify source port of a UdpPacket?

I wanted to send UdpPacket to a specific remote host (I already know the public IP and Port).
I wanted to use C#'s UdpClient class.
static int Main()
{
UdpClient client = new UdpClient();
IPEndPoint remoteEP = new IPEndPoint(IPAddress.Parse("1.2.3.4"), 9999);
byte[] data = GetData();
client.Send(data, data.Length, remoteEP);
}
When sending a packet, the UdpClient choose an available port automatically. I want to manually set the port, from which I send the packets.
Thanks for your help in advance!
Try specifying the endpoint when you create the UdpClient:
UdpClient client = new UdpClient(localEndpoint);
EDIT: Note that you can also specify just the port number:
UdpClient client = new UdpClient(localPort);
That may be somewhat simpler :)

Categories