Rod*_*ton 2 c# sockets asynchronous network-programming sendto
我有一个简单的.net 3.5sp1 Windows应用程序(在C#中)充当UDP服务器.它侦听端口,从端点接收数据,然后将其接收的内容重新传输到另一个端点(即中继,用于直播数据流).我所经历的是在连接启动约20分钟后,它开始恶化.另外我注意到它每秒吞噬大约50-100K的内存,这在GC之后永远不会被释放.我必须关闭应用程序并重新启动它.不好.我已将问题缩小到以下代码,该代码将重新传输到另一端:
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);
Run Code Online (Sandbox Code Playgroud)
有没有人有使用SendToAsync的内存泄漏的经验?
更新:
初始化套接字时,我实例化一个状态对象(仅执行一次).state对象有一个名为"buffer"的属性,它是一个字节数组.我从套接字接收数据异步如下:
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);
}
Run Code Online (Sandbox Code Playgroud)
然后,在我的回调(ReceiveDataCB)上,我正在检索异步对象,然后将字节缓冲区传递给另一个函数进行处理,然后调用上面发布的代码以便重新传输到另一端(state.buffer变为readData) .
更新#2:
根据我的直觉,我将发送代码更改为以下内容,摆脱了SocketAsyncEventArgs和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);
Run Code Online (Sandbox Code Playgroud)
当然,我添加了一个"echoCB"回调,除了调用EndSendTo之外什么都不做.内存泄漏现在消失了!我怀疑它与创建如此多的SocketAsyncEventArgs对象有关,并且异步函数挂在这些对象上,每个数据包一个(每秒33个数据包,可以快速加起来).我再次查看了SocketAsyncEventArgs的MSDN文档,我注意到在提供的服务器"示例"代码中,他们使用了一个SocketAsyncEventArgs对象池.我认为它的设计并不像我使用它那样.我认为重点是不必为每次调用实例化这些缓冲区等,因此重用它们并使服务器具有更好的性能.