use*_*428 5 c# sockets tcplistener
我有一个 Windows 服务,除其他外,它使用 .NET System.Net.Sockets 库侦听来自远程设备的传入数据。下面的示例只有一台远程设备每 60 秒推送一次数据。
每隔一段时间,该服务就会停止,并且服务器的 Windows 日志中会出现一条消息(如下所示)。
The process was terminated due to an unhandled exception.
Exception Info: System.Net.Sockets.SocketException Stack:
at System.Net.Sockets.Socket.EndReceive(System.IAsyncResult)
at Uk.Co.RCID.MoteServer.Server.SocketListener.ReceiveCallback(System.IAsyncResult)
at System.Net.LazyAsyncResult.Complete(IntPtr)
at System.Net.ContextAwareResult.CompleteCallback(System.Object)
at System.Threading.ExecutionContext.runTryCode(System.Object)
at System.Runtime.CompilerServices.RuntimeHelpers.ExecuteCodeWithGuaranteedCleanup(TryCode, CleanupCode, System.Object)
at System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext, System.Threading.ContextCallback, System.Object)
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*)
Run Code Online (Sandbox Code Playgroud)
将此事件的时间与我的上一条日志语句进行匹配后,我发现当远程设备在短时间内连接到服务两次(通常每 60 秒连接一次以推送数据)时,就会发生此致命异常。这是系统崩溃前我的最后一条日志语句。
2011-05-20 13:39:19,545 [6] INFO Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Waiting for a connection...
2011-05-20 13:39:19,545 [10] INFO Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Connection established on [10.64.128.60:11000]
2011-05-20 13:40:20,982 [6] INFO Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Waiting for a connection...
2011-05-20 13:40:20,982 [5] INFO Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Connection established on [10.64.128.60:11000]
Run Code Online (Sandbox Code Playgroud)
不想发布源代码(如果需要,我可以安排,但需要删除某些细节),套接字侦听代码基于此示例。
http://msdn.microsoft.com/en-us/library/5w7b7x5f.aspx
任何帮助是极大的赞赏。
大家好,
感谢您的回复。
我在ReceiveCallback函数中添加了更多日志记录和异常处理,今天早上在我的日志文件中发现了以下内容......
2011-05-25 04:52:26,816 [5] INFO Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Waiting for a connection...
2011-05-25 04:52:26,816 [10] INFO Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - Connection established on [10.64.128.60:11000]
2011-05-25 04:53:26,841 [10] WARN Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - SocketException thrown in ReceiveCallback
2011-05-25 04:53:26,841 [10] WARN Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - ErrorCode: [10054]
2011-05-25 04:53:26,841 [10] WARN Uk.Co.RCID.MoteServer.Server.SocketListener [(null)] - System.Net.Sockets.SocketException (0x80004005): An existing connection was forcibly closed by the remote host at System.Net.Sockets.Socket.EndReceive(IAsyncResult asyncResult) at Uk.Co.RCID.MoteServer.Server.SocketListener.ReceiveCallback(IAsyncResult ar)
Run Code Online (Sandbox Code Playgroud)
因此,关键是(如上面的一些答案中强调的那样)捕获函数内的异常ReceiveCallback并确定它们是否严重到足以杀死您的应用程序。
当客户端连接无法从半打开状态转换到完全打开状态时,EndAccept 可以并且确实会引发异常。另请注意,它会ObjectDisposedException在侦听器关闭后抛出异常,因此您必须实际查看异常并根据出现的问题确定要做什么。
EndReceive通常在客户端连接强制关闭时抛出,但您必须再次查看异常并根据抛出的异常确定要执行的操作。