C# Windows服务在执行EndAcceptCpcClient时意外终止-即在接受新的套接字客户端时
我有一个Windows服务(服务器),正在侦听端口25101。 客户端可以通过此端口连接到服务器。这是一个安全端口,因此一旦建立TCP/IP/套接字级别的连接,客户端和服务器就需要TLS握手 Windows服务是在.NET framework中使用C#编写的 源代码的摘要写在下面C# Windows服务在执行EndAcceptCpcClient时意外终止-即在接受新的套接字客户端时,c#,multithreading,sockets,ssl,tcpclient,C#,Multithreading,Sockets,Ssl,Tcpclient,我有一个Windows服务(服务器),正在侦听端口25101。 客户端可以通过此端口连接到服务器。这是一个安全端口,因此一旦建立TCP/IP/套接字级别的连接,客户端和服务器就需要TLS握手 Windows服务是在.NET framework中使用C#编写的 源代码的摘要写在下面 服务器代码 在这里,它将验证客户机/服务器TLS握手并获取SSL流。然后将用于发送和接收字节。在下面的代码摘录中,我只是编写几行代码来获取SSL流 int timeout = 15000; // Create t
服务器代码
在这里,它将验证客户机/服务器TLS握手并获取SSL流。然后将用于发送和接收字节。在下面的代码摘录中,我只是编写几行代码来获取SSL流
int timeout = 15000;
// Create the SslStream using the client's network stream.
var sslStream = new SslStream(client.GetStream(), false);
// Authenticate the server but don't require the client to authenticate.
Task serverAuth = sslStream.AuthenticateAsServerAsync(serverCertificate, false, SslProtocols.None, true);
if (await Task.WhenAny(serverAuth, Task.Delay(timeout)) == serverAuth)
{
// task completed within timeout
return sslStream;
}
else
{
// timeout logic
throw new System.Exception("AuthenticateAsServerAsync timeout after " + timeout + " millisoconds");
}
问题陈述
在正常情况下,它工作正常。服务器可以正常运行数周甚至数月,没有任何问题,数百万个套接字客户端连接被打开,然后关闭,没有任何问题 在极少数情况下,AuthenticateServerAsync函数不会获取SSL流。所以15秒后我就超时了。但在此之后,侦听器也停止接受新的连接,即使服务器已启动并正在运行,也没有新的客户端可以与服务器连接。这是我最初的问题 由于这种情况很少发生,所以我在.NETC#中编写了一个测试应用程序,它是一个TCP/IP客户端,向服务器发出大量连接请求。大约每秒10次。我正在通过批处理文件停止和启动此测试应用程序。使用这个测试应用程序(在运行大约3-4小时后)-我能够终止服务器进程 下面是正在发生的事情
client = m_listener.EndAcceptTcpClient(ar);
上面的行产生了以下异常
2021-04-20 19:48:19.4724|ERROR|OvationServerLib.RelayConnections.DeviceServer.DoAcceptTcpClientCallback: Exception EndAcceptTcpClient System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host
at System.Net.Sockets.Socket.EndAccept(Byte[]& buffer, Int32& bytesTransferred, IAsyncResult asyncResult)
at System.Net.Sockets.Socket.EndAccept(IAsyncResult asyncResult)
at System.Net.Sockets.TcpListener.EndAcceptTcpClient(IAsyncResult asyncResult)
at OvationServerLib.RelayConnections.DeviceServer.DoAcceptTcpClientCallback(IAsyncResult ar) in C:\Development\Relay Server\fb4_relay_server\FB4_Relay_Server\Fb4RelayServer\OvationServerLib\RelayConnections\DeviceServer.cs:line 54
但是在事件查看器中,我看到了稍微不同的异常,请参见下文
Application: OvationServerService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.NullReferenceException
at OvationServerLib.RelayConnections.DeviceServer.DoAcceptTcpClientCallback(System.IAsyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr)
at System.Net.ContextAwareResult.CompleteCallback(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Net.ContextAwareResult.Complete(IntPtr)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
因此,我的问题是:
1-为什么我的服务器在endAcceptCpcClient产生异常并且我已经在处理异常时终止
2-为什么在15秒后超时AuthenticateServerAsync会停止侦听器接受新连接。我必须设置一些超时,因为我们不能在这个API上永远等待
为什么我的服务器在EndAcceptCpcClient产生异常并且我已经在处理该异常时终止
您正在处理(并记录)SocketException。但是您的DOACCEPTCPClientCallback
只是在client
设置为null
的情况下继续运行。与其继续,不如从回调返回(因为套接字不再可行)
为什么在15秒后超时AuthenticateAsServerAsync会停止侦听器接受新连接。我必须设置一些超时,因为我们不能在这个API上永远等待
每当套接字操作超时时,应关闭套接字。这对于“悲观”超时尤其如此,例如
Task.wheny
。这种“超时”实际上并不会停止authenticateaserverasync
调用;您需要关闭套接字以强制停止authenticatesServerAsync
操作。我猜,如果endAcceptCpcClient
抛出,它将不会设置客户端。所以它可能是空的。如果随后捕获SocketException并继续使用客户端
,您将遇到一个NRE。你能确认/排除这一点吗?你是对的,这是一个有效的观点。我会检查一下并试一试。ThanksI我已在超时AuthenticateTaserverAsync操作后关闭套接字连接。这是一个非常正确的观点。我没有在上面的问题中包含这部分代码,但我肯定要关闭套接字。我还将ReceiveTimeout在套接字上放置了15秒,但我仍然需要对此进行测试。
Application: OvationServerService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.NullReferenceException
at OvationServerLib.RelayConnections.DeviceServer.DoAcceptTcpClientCallback(System.IAsyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr)
at System.Net.ContextAwareResult.CompleteCallback(System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object, Boolean)
at System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
at System.Net.ContextAwareResult.Complete(IntPtr)
at System.Net.LazyAsyncResult.ProtectedInvokeCallback(System.Object, IntPtr)
at System.Net.Sockets.BaseOverlappedAsyncResult.CompletionPortCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)
at System.Threading._IOCompletionCallback.PerformIOCompletionCallback(UInt32, UInt32, System.Threading.NativeOverlapped*)