I have a simple .net 3.5sp1 windows application (in C#) that acts as a UDP server. It listens on a port, receives data from an endpoint, and then retransmits what it receives to another endpoint (i.e. a relay, for a live broadcast data stream). What I'm experiencing is after the connection is up for about 20 minutes, it starts to deteriorate. Also I notice that it is gobbling up about 50-100K of memory per second, which doesn't ever get released after GC. I have to close the app and restart it. Not good. I have narrowed down the problem to the following code, which does the retransmission to the other side:
var sendBuffer = new byte[readCount];
Array.Copy(readData, sendBuffer, readCount);
SocketAsyncEventArgs args = new SocketAsyncEventArgs();
args.RemoteEndPoint = p.EP;
args.SetBuffer(sendBuffer, 0, sendBuffer.Length);
SwitchWindow.LineSocket.SendToAsync(args);
Does anyone have any experience with memory leaks with SendToAsync?
UPDATE:
I instantiate a state object (only done once) when the socket is initialized. The state object has a property called "buffer", which is a byte array. I receive data async from the socket like such:
private void beginReceiveData(ref MessageState state)
{
var ipeSender = new IPEndPoint(IPAddress.Any, 0);
var epSender = (EndPoint)ipeSender;
state.workSocket = LineSocket;
state.EP = epSender;
state.workSocket.BeginReceiveFrom(state.buffer, 0, MessageState.BufferSize,
SocketFlags.None, ref epSender,
new AsyncCallback(ReceiveDataCB),
state);
}
And, then on my callback (ReceiveDataCB), I am retrieving the async object, and then passing the byte buffer to another function for processing, which in turn calls the code posted above for retransmission to the other side (state.buffer becomes readData).
UPDATE #2:
Following my gut, I changed the sending code to the following, getting rid of SocketAsyncEventArgs and SendToAsync:
var sendBuffer = new byte[readCount];
Array.Copy(readData, sendBuffer, readCount);
SwitchWindow.LineSocket.BeginSendTo(
sendBuffer, 0, sendBuffer.Length, SocketFlags.None,
p.EP, new AsyncCallback(echoCB), null);
And, of course, I added an "echoCB" callback that does nothing other than calling EndSendTo. The memory leak is now gone! I suspect it had something to do with creating so many SocketAsyncEventArgs objects, and the async function hanging onto these, one for each packet (at 33 packets per second, that can add up fast). I looked once again at the MSDN documentation for SocketAsyncEventArgs, and I noticed that on the server "example" code provided, they used a pool of SocketAsyncEventArgs objects. I don't think its really designed to work the way I was using it. I think the whole point is to not have to instantiate these buffers, etc, for each call, therefore reusing them and allowing the server better performance.