I n开发者_JS百科eed to write a very high load UDP server. I'm using .Net. How do I use the Socket class to achieve this?
I am familiar with the winsock API, and completion ports, and what i would do there, is to use several threads to accept sockets using a completion port, and also to receive in the same manner.
My server needs to process a LOT of small UDP packets very quickly, and i want to receive them asynchronously, how do i do this using .net?
I thought of calling BeginReceive several times, but that kinda seems silly...
If anyone has a good .net example for this it would of course help a lot.
What I have found to minimize dropped packets is to read from the socket asynchronously as you mentioned, but to put the bytes read into a thread safe queue, then have another thread read off the queue and process the bytes. If you are using .Net 4.0 you could use ConcurrentQueue:
public class SomeClass {
ConcurrentQueue<IList<Byte>> _Queue;
Byte[] _Buffer;
ManualResetEvent _StopEvent;
AutoResetEvent _QueueEvent;
private void ReceiveCallback(IAsyncResult ar) {
Socket socket = ar.AsyncState as Socket;
Int32 bytesRead = socket.EndReceive(ar);
List<Byte> bufferCopy = new List<byte>(_Buffer);
_Queue.Enqueue(bufferCopy);
_QueueEvent.Set();
if(!_StopEvent.WaitOne(0)) socket.BeginReceive(...);
return;
}
private void ReadReceiveQueue() {
WaitHandle[] handles = new WaitHandle[] { _StopEvent, _QueueEvent };
Boolean loop = true;
while (loop) {
Int32 index = WaitHandle.WaitAny(handles);
switch (index) {
case 0:
loop = false;
break;
case 1:
// Dequeue logic here
break;
default:
break;
}
}
}
}
Note: the _StopEvent is a ManualResetEvent so that both the ReceiveCallback and ReadReceiveQueue methods can use the same event to shut down cleanly.
If you only have a single socket and you can process UDP packets independently of each other, then the best approach would actually be to use a thread pool where each thread invokes a blocking Receive. The OS will take care of waking up one of the waiting threads to receive/process the packet. That way you can avoid any overhead introduced by the async-I/O routines.
精彩评论