解决Windows套接字错误WSAENOBUFS(10055)

时间:2017-11-07 12:38:46

标签: windows sockets delphi

我们的应用程序具有主动连接到客户的内部工厂网络的功能,并在检查事件发生时发送消息。客户将其机器和应用程序的IP地址和端口号输入我们的软件。

我在阻止模式下使用TClientSocket,并为OnConnectOnError事件提供了回调函数。假设已激活上述功能,当应用程序启动时,我在一个单独的线程中调用以下代码:

// Attempt active connection
try
    m_socketClient.Active := True;
except
end;

// Later...
// If `OnConnect` and socket is connected...send some data!
// If `OnError`...call `m_socketClient.Active := True;` again

当IP +端口有效时,该功能运行良好。但如果没有,在几千个错误(以及几个小时甚至几天)之后,最终会发生Windows套接字错误10055(WSAENOBUFS)并且应用程序崩溃。

this one from ServerFrameworkthis one from Microsoft等各种文章讨论exhausting the Windows non-paged pool并提及(1)主动管理未完成的异步发送操作数量,以及(2)释放用于的数据缓冲区I / O操作。

我的问题是如何实现这一目标并且是三方面的:

A)我做错了记忆被泄漏了吗?例如,OnError处理程序中是否有一些缺少的清理代码?

B)如何监控I / O缓冲区以查看它们是否已耗尽?我已经使用Process Explorer来确认我的应用程序是泄漏的原因,但理想情况下我需要一些程序化的方法来测量它。

C)除了重新启动应用程序之外,有没有办法让Windows清除或释放I / O操作数据缓冲区?

Delphi中的代码示例,C / C ++,C#罚款。

1 个答案:

答案 0 :(得分:0)

A)资源泄漏的原因是编程错误。发生OnError事件时,应调用Socket.Close()以释放与套接字关联的低级资源。

B)内存泄漏未显示在进程的标准Working Set内存使用中。需要监视属于您的流程的打开句柄,这可以通过GetProcessHandleCount进行监控。请参阅Delphi中的this answer,该版本经过测试并运行良好。此answer in C++未经过测试,但答案已被接受,因此应该可以使用。当然,您应该能够直接在C ++中使用GetProcessHandleCount

C)经过大量研究,我必须得出结论,就像正常的内存泄漏一样,你不能只是要求Windows清理"在你之后!句柄资源已被您的应用程序泄露,您必须找到并修复原因(参见上面的A和B)。