我有一个异步服务器套接字侦听器和数千个客户端。
下面的代码按预期工作,直到一段时间(这是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.");
}