I have a UDP server in a .NETMF application (the solution would probably be similar for classic .NET Framework 4.5, except that there aren't some classes and methods such as UdpClient). I "start listening" on a socket like this:
_server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_server.Bind(ep);
And now I want to accept data from a several threads (one thread for every IPEndPoint). The point is to maximize speed. (Note that I am using .NETMF so UdpClient class is not availible).
I had two ideas. First was to create a thread for each expected IPEndPoint
and accept/process data there. However the problem is that after a thread accepts data and determines that the accepted source IP/port is different than the assigned IP/port to this thread, this data is thrown away and is not availible for the other appropriate thread anymore. Is there a simple way to fix that? See sample code here:
using System;
using Microsoft.SPOT;
using System.Net;
using System.Net.Sockets;
using System.Threading;
namespace MFConsoleApplication1
{
internal class ServerThread
{
internal IPEndPoint EP { get; private set; }
internal Socket Server { get; private set; }
public ServerThread(IPEndPoint ep, Socket s)
{
EP = ep;
Server = s;
new Thread(() =>
{
byte[] buffer = new byte[2048];
int byteCount;
EndPoint recvEP = new IPEndPoint(IPAddress.Any, 0);
while (true)
{
byteCount = Server.ReceiveFrom(buffer, ref recvEP);
if (!recvEP.Equals(EP)) cotinue; //this makes the thread to ignore
// to ignore the data as EP is different,but it throw the data away
// Process data
Debug.Print(byteCount.ToString()); // For example
}
}).Start();
}
}
}
The other idea is to have one thread which accepts data. When a data chunk is accepted, based on the source IP/port, this thread will create a new Thread to process data. This way doesn't seem to be too elegant as it would require creating tens or hundreds of threads per second. A little imporvement would perhaps be to create threads for each expected IPEndPoint, and to keep them in suspended state till a data for the particular End Point is available.
What is the solution of this problem please?
Thanks for any efforts.
Update The natural approach would be:
_server = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
_server.Bind(ep);
while (true)
{
byteCount = Server.ReceiveFrom(buffer, ref recvEP);
// Process data
Debug.Print(byteCount.ToString()); // For example
}
However I need to process data on the basis of the address of the sender. So I could perhaps add a line with similar meaning like:
new Thread(new ParameterizedThreadStart(ProcessData)).Start(recvEP);
and execute it each time after some data is received, but as the server receives tens - hundreds of messages per second this woudn't be too elegant either.
Please suggest an optimum solution for my problem.