У меня есть довольно общий сервер сокетов C #, который использует асинхронные методы классов сокетов - BeginAccept (), BeginReceive () и т. Д. Этот сервер отлично работал в течение последних 4 лет на многих сайтах клиентов, работающих под управлением Win Server 2003 Недавно я установил его на 64-битном сервере Windows Server 2008 R2. Все выглядит нормально, пока первый клиент не подключится и не вызовет вызовы BeginReceive () и BeginAccept () в обработчике принятия. Когда это происходит, загрузка процессора увеличивается до 100% и остается такой, пока я не закрою сокет прослушивания.
Не уверен, что это имеет значение, но сервер работает на виртуальной машине.
Много тестировали, но, похоже, ничего не помогло. Используя Process Explorer, я вижу, что два потока запускаются вскоре после вызовов BeginReceive () / BeginAccept (), и именно они потребляют процессор. К сожалению, я не могу воспроизвести эту проблему на моей 64-разрядной рабочей станции Win7.
Я провел много исследований, и все, что я нашел до сих пор, это следующие две статьи базы знаний, в которых подразумевается, что Server 2008 R2 может иметь проблему с компонентами TCP / IP, но они доступны только в качестве оперативных исправлений. : KB2465772 и KB2477730. Я не хочу, чтобы мой клиент установил их, пока я не буду уверен, что они исправят проблему.
Кто-нибудь еще имел эту проблему? Если да, что вам нужно было сделать, чтобы решить эту проблему?
Вот метод, который, как я считаю, вызывает ситуацию:
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);
}
}