C# TCP套接字连接

C# TCP套接字连接,c#,sockets,tcplistener,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:

我有一个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*)  
将此事件的时间与我的上一个日志语句匹配后,我发现当远程设备在短时间内连接到服务两次时(通常,它每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]
无需发布源代码(如果需要,我可以安排,但需要删除某些细节),套接字侦听代码基于此示例

非常感谢您的帮助


大家好,

谢谢你的回复

我在
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)

因此,关键是(如上面一些答案中突出显示的)捕获
ReceiveCallback
函数中的异常,并确定它们是否严重到足以杀死应用程序

我要做的第一件事是检查抛出的
SocketException
中的
ErrorCode
属性的值。在中查找此值,以查找可能出错的指针


如果您发布了错误代码,那么我可能可以进一步提供帮助。

如果您的代码与示例非常接近,那么您应该尝试一下:

int read=handler.EndReceive(ar)

ReceiveCallback
函数中,因为它可能很简单,就像在尝试接收时关闭套接字连接一样


您可以继续,而不是终止进程。

您应该始终在所有回调方法中捕获(异常错误)
DO记录异常

原因是在主线程之外的任何其他线程中抛出的所有未处理异常都将终止应用程序


您应该将套接字回调中的任何异常视为客户端已断开连接。当然,您可能会遇到致命的异常,如
OutOfMemoryException
,这些异常会终止您的应用程序。但在大多数情况下,这是不可能的。

当客户端连接无法从半开放状态转换到完全开放状态时,EndAccept可以并且确实引发异常。还请注意,在侦听器关闭后,它将抛出一个
ObjectDisposedException
,因此您必须实际查看异常,并根据出现的错误确定要执行的操作


EndReceive
通常在强制关闭客户端连接时抛出,但您必须再次查看异常,并根据抛出的异常确定要执行的操作。

正在捕获的异常的
InnerException
属性中是否存在内部异常?我想在你的代码中可能会有一些东西被抛出,你正在从套接字接收数据。不幸的是,我没有这些信息。由于错误很少发生,因此需要一些时间来重新创建更多日志记录的问题。我将尝试用一个模拟的远程设备重新创建它。谢谢到目前为止的提示。我将添加更多日志以检索到目前为止请求的信息。这一建议似乎是可能的,因为远程设备是嵌入式电子设备,并且可能在此期间关闭连接。谢谢。我在ReceiveCallback函数中添加了更多日志记录,并在昨晚的日志文件中发现了以下内容。。。