Reputation: 41
I'm new to C# UDP coding and I have some 'strange' behaviour when using an UDP client locally on my pc. I want to send UDP data from one port (11000) on my pc to another port (12000) on the same pc.
This is a snippet from my code :
public class MyClass
{
//Creates a UdpClient for reading incoming data.
private UdpClient udpClient;
private Thread thread;
private const String IPADDR = "127.0.0.1";
public MyClass()
{
udpClient = new UdpClient(11000);
udpClient.Connect(IPAddress.Parse(IPADDR), 12000);
this.thread = new Thread(new ThreadStart(this.Execute));
this.thread.Name = "Udp";
this.thread.Start();
SendData("The quick brown fox jumps over the lazy dog");
}
private void Execute()
{
try
{
// Blocks until a message returns on this socket from a remote host.
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Any, 0);
Byte[] receiveBytes = this.udpClient.Receive(ref remoteIpEndPoint);
Console.WriteLine("Data received");
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void SendData(String data)
{
Console.WriteLine("Sending...");
try
{
this.udpClient.Send(System.Text.Encoding.ASCII.GetBytes(data), data.Length);
}
catch (Exception e)
{
Console.WriteLine(String.Format("Exception {0}", e.Message));
}
}
}
If I run this, I get an exception :
Sending...
System.Net.Sockets.SocketException: An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.ReceiveFrom(Byte[] buffer, Int32 offset, Int32 size, SocketFlags socketFlags, EndPoint& remoteEP)
at System.Net.Sockets.UdpClient.Receive(IPEndPoint& remoteEP)
at test.MyClass.Execute() in C:\Temp\test\Class1.cs:line 40
The exception seems to occur on this line :
Byte[] receiveBytes = this.udpClient.Receive(ref remoteIpEndPoint);
At the moment of the SendData(), the Receive is throwing the exception. When not doing the send, I don't get the exception. It looks like the send is causing the receive to return with an exception.
When I use the real ip address of my pc, I have the same behaviour. However, when I use any other ip address, even if it's unassigned to any pc (e.g. 192.168.10.10), it's working well : it sends the string and the Receive() keeps waiting for incoming data.
Upvotes: 4
Views: 7041
Reputation: 70652
The error happens because there is no socket open on the port to which you are sending.
For the purposes of simply testing UDP communications, you can fix your code example simply by changing the port to which you are sending. I.e. change the Connect()
method call to this:
udpClient.Connect(IPAddress.Parse(IPADDR), 11000);
This will cause the socket to send to itself. Your code will work successfully with just this change.
For the record, here is about the simplest possible demonstration code that uses UdpClient
:
UdpClient client = new UdpClient(0, AddressFamily.InterNetwork);
byte[] datagram = Encoding.ASCII.GetBytes("hello world!");
IPEndPoint ipEndPoint = new IPEndPoint(IPAddress.Loopback, ((IPEndPoint)client.Client.LocalEndPoint).Port);
client.Send(datagram, datagram.Length, ipEndPoint);
datagram = client.Receive(ref ipEndPoint);
Console.WriteLine("Received: \"" + Encoding.ASCII.GetString(datagram) + "\"");
Of course, in a real network I/O situation, you will have two endpoints, each bound to its own local port, sending to the other endpoint's port. So neither your code example, nor this simpler one I present is very useful as an actual working program. But it does allow you to learn some things about how the socket API works.
Upvotes: 1
Reputation: 716
You are trying to send from one socket (UdpClient which is socket wrapper) to itself. Thats not how the things work in UDP (nor in other IP protocols). You need 2 sockets. One for sending one for receiving. Connect method is poorly named since UDP protocol is conectionless but thats not your fault.
Other than that you need to put socket in listening state before sending to it. So you first need to start thread that listens and then send.
You need to better design your program but this will work:
class Program
{
static void Main(string[] args)
{
MyClass mc = new MyClass();
}
}
public class MyClass
{
//Creates a UdpClient for reading incoming data.
private UdpClient udpClient;
private UdpClient recipient;
private Thread thread;
private const String IPADDR = "127.0.0.1";
public MyClass()
{
recipient = new UdpClient(new IPEndPoint(IPAddress.Parse(IPADDR), 12000));
this.thread = new Thread(new ThreadStart(this.Execute));
this.thread.Name = "Udp";
this.thread.Start();
udpClient = new UdpClient(11000);
udpClient.Connect(IPAddress.Parse(IPADDR), 12000);
SendData("The quick brown fox jumps over the lazy dog");
}
private void Execute()
{
try
{
// Blocks until a message returns on this socket from a remote host.
IPEndPoint remoteIpEndPoint = new IPEndPoint(IPAddress.Parse(IPADDR), 11000);
Byte[] receiveBytes = this.recipient.Receive(ref remoteIpEndPoint);
Console.WriteLine("Data received: " + Encoding.ASCII.GetString(receiveBytes));
}
catch (Exception e)
{
Console.WriteLine(e.ToString());
}
}
public void SendData(String data)
{
Console.WriteLine("Sending...");
try
{
this.udpClient.Send(System.Text.Encoding.ASCII.GetBytes(data), data.Length);
}
catch (Exception e)
{
Console.WriteLine(String.Format("Exception {0}", e.Message));
}
}
}
Upvotes: 0