【问题标题】:TCP Socket ConnectionsTCP 套接字连接
【发布时间】:2011-08-31 18:39:02
【问题描述】:

我有一个 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]

不想发布源代码(如果需要我可以安排,但需要删除某些细节),套接字监听代码基于此示例。

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)

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

【问题讨论】:

  • 您要捕获的异常的InnerException 属性中是否存在内部异常?我认为在您从套接字接收数据的代码中可能会出现一些问题。
  • 很遗憾,我没有这些信息。由于错误很少发生,因此需要一些时间来重新创建更多日志记录的问题。我将尝试使用模拟的远程设备重新创建它。

标签: c# sockets tcplistener


【解决方案1】:

当客户端连接无法从半开状态转换到全开状态时,EndAccept 可以并且确实会引发异常。另请注意,它会在侦听器关闭后抛出ObjectDisposedException,因此您必须实际查看异常并根据出现的问题确定要做什么。

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

【讨论】:

  • 我在 ReceiveCallback 函数中添加了更多日志记录,昨晚在我的日志文件中发现了以下内容...
【解决方案2】:

您应该在所有回调方法中始终使用catch (Exception err)记录异常。

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

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

【讨论】:

    【解决方案3】:

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

    int read = handler.EndReceive(ar);

    ReceiveCallback 函数中,因为它可能很简单,例如在您尝试接收时关闭套接字连接。

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

    【讨论】:

    • 这个建议似乎是可行的,因为远程设备是嵌入式电子设备,它有可能在此期间关闭连接。谢谢。
    【解决方案4】:

    我要做的第一件事是检查抛出的SocketExceptionErrorCode 属性的值。在 winsock error code list 中查找此值,以获取一些指向可能出现问题的指针。

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

    【讨论】:

    • 感谢到目前为止的提示。我将添加更多日志记录以检索到目前为止已请求的信息。
    猜你喜欢
    • 2023-03-21
    • 1970-01-01
    • 1970-01-01
    • 2010-12-01
    • 2021-09-10
    • 2020-11-30
    • 2013-04-29
    • 2014-04-08
    相关资源
    最近更新 更多