C# 在Windows Server 2008 R2上使用异步套接字会导致100%的CPU使用率
我有一个相当通用的C#socket服务器,它使用socket类的异步方法—BeginAccept()、BeginReceive(),等等。在过去4年中,该服务器在许多运行Win server 2003的客户站点上运行得非常好。最近,我将其安装在Windows Server 2008 R2服务器上,64位。在第一个客户端连接并在accept处理程序中发出BeginReceive()和BeginAccept()调用之前,一切看起来都很正常。当这种情况发生时,CPU使用率将达到100%,并一直保持这种状态,直到我关闭侦听套接字 不确定这是否重要,但服务器正在虚拟机中运行 已经做了很多测试,但似乎没有任何帮助。使用Process Explorer,我可以看到两个线程在BeginReceive()/BeginAccept()调用后很快就启动了,它们是消耗处理器的线程。不幸的是,我无法在我的Win7 64位工作站上重现此问题 我做了很多研究,到目前为止,我所发现的只是以下两篇KB文章,它们暗示Server2008R2可能与TCP/IP组件有问题,但它们只能作为热修复程序提供:KB2465772和KB247730。我不愿意让我的客户安装它们,直到我更确定他们会解决问题 还有其他人有这个问题吗?如果是,您必须采取什么措施来解决此问题 以下是我认为导致这种情况的方法:C# 在Windows Server 2008 R2上使用异步套接字会导致100%的CPU使用率,c#,windows-server-2008,cpu-usage,asyncsocket,C#,Windows Server 2008,Cpu Usage,Asyncsocket,我有一个相当通用的C#socket服务器,它使用socket类的异步方法—BeginAccept()、BeginReceive(),等等。在过去4年中,该服务器在许多运行Win server 2003的客户站点上运行得非常好。最近,我将其安装在Windows Server 2008 R2服务器上,64位。在第一个客户端连接并在accept处理程序中发出BeginReceive()和BeginAccept()调用之前,一切看起来都很正常。当这种情况发生时,CPU使用率将达到100%,并一直保持这种
private void AcceptCallback(IAsyncResult result) {
ConnectionInfo connection = new ConnectionInfo();
try {
// Finish accept.
Socket listener = (Socket)result.AsyncState;
connection.Socket = listener.EndAccept(result);
connection.Request = new StringBuilder(256);
// Start receive and a new accept.
connection.Socket.BeginReceive(connection.Buffer, 0,
connection.Buffer.Length, SocketFlags.None,
new AsyncCallback(ReceiveCallback), connection);
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), listener);
// CPU usage spikes at 100% shortly after this...
}
catch (ObjectDisposedException /*ode*/) {
_log.Debug("[AcceptCallback] ObjectDisposedException");
}
catch (SocketException se) {
connection.Socket.Close();
_log.ErrorFormat("[AcceptCallback] Socket Exception ({0}: {1} {2}", connection.ClientAddress, se.ErrorCode, se.Message);
}
catch (Exception ex) {
connection.Socket.Close();
_log.ErrorFormat("[AcceptCallback] Exception {0}: {1}", connection.ClientAddress, ex.Message);
}
}
该问题是由于在设置侦听器套接字时多次调用BeginAccept()引起的。不知道为什么该问题只发生在64位服务器上,但按如下所示更改代码修复了该问题 原始代码:
public SetupServerSocket() {
IPEndPoint myEndPoint = new IPEndPoint(IPAddress.Any, _port);
// Create the socket, bind it, and start listening.
_serverSocket = new Socket(myEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(myEndPoint);
_serverSocket.Listen((int)SocketOptionName.MaxConnections);
for (int i = 0; i < 10; i++) {
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
}
}
publicsetupserversocket(){
IPEndPoint myEndPoint=新的IPEndPoint(IPAddress.Any,_port);
//创建套接字,绑定它,然后开始侦听。
_serverSocket=新套接字(myEndPoint.Address.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
_绑定(myEndPoint);
_侦听((int)SocketOptionName.MaxConnections);
对于(int i=0;i<10;i++){
_beginacept(新的异步回调(AcceptCallback),\u serverSocket);
}
}
对下列事项:
public SetupServerSocket() {
IPEndPoint myEndPoint = new IPEndPoint(IPAddress.Any, _port);
// Create the socket, bind it, and start listening.
_serverSocket = new Socket(myEndPoint.Address.AddressFamily, SocketType.Stream, ProtocolType.Tcp);
_serverSocket.Bind(myEndPoint);
_serverSocket.Listen((int)SocketOptionName.MaxConnections);
//for (int i = 0; i < 10; i++) {
_serverSocket.BeginAccept(new AsyncCallback(AcceptCallback), _serverSocket);
//}
}
publicsetupserversocket(){
IPEndPoint myEndPoint=新的IPEndPoint(IPAddress.Any,_port);
//创建套接字,绑定它,然后开始侦听。
_serverSocket=新套接字(myEndPoint.Address.AddressFamily,SocketType.Stream,ProtocolType.Tcp);
_绑定(myEndPoint);
_侦听((int)SocketOptionName.MaxConnections);
//对于(int i=0;i<10;i++){
_beginacept(新的异步回调(AcceptCallback),\u serverSocket);
//}
}
我知道您在“Wire Performance”一文中找到了SetupServerSocket()-如果您有快速的新客户端连接,最初的10x for循环将支持10个侦听线程。您已将其更改为一个侦听器。如果Win2k8r2有这样一个bug,这可能是唯一可能的解决方案。您可能希望确保客户端中有健壮的连接重试代码
使用.NET中的高性能插座更接近电线
使用server 2012 R2时,我似乎遇到了simelar问题。除了我的应用程序运行了好几个星期,然后突然我得到了高CPU使用率。分析表明使用cpu的是
System.net.Socket.beginReceive()