Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Windows服务在执行EndAcceptCpcClient时意外终止-即在接受新的套接字客户端时_C#_Multithreading_Sockets_Ssl_Tcpclient - Fatal编程技术网

C# Windows服务在执行EndAcceptCpcClient时意外终止-即在接受新的套接字客户端时

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

我有一个Windows服务(服务器),正在侦听端口25101。 客户端可以通过此端口连接到服务器。这是一个安全端口,因此一旦建立TCP/IP/套接字级别的连接,客户端和服务器就需要TLS握手

Windows服务是在.NET framework中使用C#编写的

源代码的摘要写在下面


服务器代码


在这里,它将验证客户机/服务器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*)