У меня есть прослушиватель сокетов асинхронного сервера и тысячи клиентов.
Приведенный ниже код работает, как и ожидалось, до некоторого времени (который отличается, иногда 1 час, иногда 3 дня), затем не принимает новые подключения.Когда это событие происходит, мой процесс все еще работает, и порт, который сервер прослушивает, показывая все еще прослушивающий Мониторинг ресурсов.Я использую wireshark для определения клиентских подключений в этот период.
Поэтому я добавляю несколько журналов, чтобы найти причину, почему?Я кеширую некоторые вещи, но я не знаю, что это вызывает.Я обнаружил, что BeginReceive
не запускает новый поток, а текущий поток продолжает работать по моему OnClientConnected
методу.Поэтому сервер не принимает новые подключения.
protected Socket listener;
protected ManualResetEvent acceptDone = new ManualResetEvent(false);
public void Start(int port) {
try {
var ipEndPoint = new IPEndPoint(IPAddress.Any, port);
listener = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1);
LingerOption myOpts = new LingerOption(false, 0);
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.Linger, myOpts);
listener.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.DontLinger, true);
listener.Bind(ipEndPoint);
listener.Listen(100000);
Logger.Info(
$"{ServiceInformation.LocalIpAddress}:{port} listining.");
StartListening();
} catch (Exception e) {
Logger.Error(
$"{ServiceInformation.LocalIpAddress}:{port} not listening.",
e);
}
}
private void StartListening() {
try {
while (true) {
try {
Logger.Info("StartListening acceptdone reset." + Thread.CurrentThread.ManagedThreadId);
acceptDone.Reset();
Logger.Info("StartListening begin accept." + Thread.CurrentThread.ManagedThreadId);
listener.BeginAccept(OnClientConnected, listener);
Logger.Info("StartListening acceptdone waitone." + Thread.CurrentThread.ManagedThreadId);
acceptDone.WaitOne();
} catch (Exception e) {
Logger.Error("StartListening error." + Thread.CurrentThread.ManagedThreadId, e);
}
}
} catch (Exception e) {
Logger.Error("while error" + Thread.CurrentThread.ManagedThreadId, e);
}
}
protected void OnClientConnected(IAsyncResult asyncResult) {
acceptDone.Set();
Logger.Info("OnClientConnected acceptdone set." + Thread.CurrentThread.ManagedThreadId);
//I am expecting here to changing current thread id. If it change my listener working.
Socket client;
try {
var _listener = (Socket)asyncResult.AsyncState;
client = _listener.EndAccept(asyncResult);
Logger.Info($"Client connected: {client.RemoteEndPoint}" + Thread.CurrentThread.ManagedThreadId);
} catch (ObjectDisposedException) {
Logger.Error($"Listening socket has been closed." + Thread.CurrentThread.ManagedThreadId);
return;
}
try {
var state = GetStateObject(client);
client.BeginReceive(state.Buffer, 0, StateObject.BufferSize, 0, OnMessageReceived, state);
} catch (Exception e) {
Logger.Error($"Listening socket has been closed.", e);
client.Shutdown(SocketShutdown.Both);
client.Close();
}
Logger.Info("OnClientConnected finish.");
}