【问题标题】:Socket server problem: socket server crashing套接字服务器问题:套接字服务器崩溃
【发布时间】:2021-08-30 09:53:16
【问题描述】:

我们有一个 .Net 应用程序作为服务运行,使用 TCPClient 在 TCP 端口上侦听流量。它可以成功运行数天和数千个连接,但在某些时候, 服务在 Windows 事件查看器中崩溃并出现此异常:

问题签名:

Application: WindowsService.exe
Framework Version: v4.0.30319
Description: The process was terminated due to an unhandled exception.
Exception Info: System.Net.Sockets.SocketException
   at System.Net.Sockets.Socket.BeginReceive(Byte[], Int32, Int32, System.Net.Sockets.SocketFlags, System.AsyncCallback, System.Object)
   at WindowsService.Connexion.AcceptCallback(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*)

提前谢谢你:)

【问题讨论】:

  • docs.tibbo.com/taiko/sock_tcp_reconnects 这可能有助于理解它。尝试处理异常并在发生这种情况时使用 Socket.EndReceive。 docs.microsoft.com/en-us/dotnet/api/…
  • 嗨,@simali。您能否在处理新连接和接收数据的位置添加代码?
  • 嗨,@simali,我修改了答案,但不是最后,所以我需要你分享错误代码,这非常重要,请检查我的升级。

标签: c# .net sockets socketexception


【解决方案1】:

Simali,欢迎来到 Stackoverflow。

首先,当您发布问题时,要求将代码发布到您的问题中,而不是在 cmets 中。 StackOverflows 允许您编辑您的问题。这次,我将您的代码添加到我的答案中:

private static void AcceptCallback(IAsyncResult AR) {
    Socket socket; 
    try { 
        socket = serverSocket.EndAccept(AR); 
        Log.CreatLog("Client connected, server waiting for request ... "); 
        
        socket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallbackAsync, socket); 
        
        serverSocket.BeginAccept(AcceptCallback, null); 
    }catch (ObjectDisposedException e) { 
        Log.CreatLog("ObjectDisposedException !!!"); return; 
    } 
}

现在,正如您的堆栈错误所示,错误位于 socket.BeginReceive 并且抛出的异常是 SocketException,这是 BeginReceive 可以抛出的四种不同异常之一:

  • ArgumentNullException
  • SocketException,表示:尝试访问套接字时出错。
  • ObjectDisposedException
  • ArgumentOutOfRangeException

这个信息可以在这个link查看。

您的程序正在崩溃,因为您正在处理 ObjectDisposedException 而不是其他人,例如在本例中的 SocketException。所以你应该添加SocketException 并打印程序在异常时刻得到的消息和堆栈错误;像这样:

private static void AcceptCallback(IAsyncResult AR) {
    Socket socket; 
    try { 
        socket = serverSocket.EndAccept(AR); 
        Log.CreatLog("Client connected, server waiting for request ... "); 
        
        socket.BeginReceive(buffer, 0, BUFFER_SIZE, SocketFlags.None, ReceiveCallbackAsync, socket); 
        
        serverSocket.BeginAccept(AcceptCallback, null); 
    }catch (ObjectDisposedException e) { 
        Log.CreatLog("ObjectDisposedException !!!" + e); return; 
    } 
    catch (SocketException e) { 
        Log.CreatLog("SocketException !!!: " + e); return; 
    } 
    catch (ArgumentOutOfRangeException e) { 
        Log.CreatLog("ArgumentOutOfRangeException !!!" + e); return; 
    } 
    catch (ArgumentNullException e) { 
        Log.CreatLog("ArgumentNullException !!!" + e); return; 
    } 
}

我添加了其他异常,因为我不知道您的程序是否有其他套接字接收问题。

通过这种方式,您将获得有关错误的更多信息,并且您的程序将有更多机会通过异常。

重要提示:与此异常在socket.BeginReceive 上升的方式相同,您可以在此函数中包含更多异常,例如BeginAccept。所以我建议你检查异步套接字抛出的所有可能的异常并处理它们。

**

升级(7 月 5 日):

**

Simail:要添加有关我的答案的更多信息,您的输出不足以给您正确的答案。 SocketException 可能有多种原因,因此您需要打印 ErrorCode,如 windows 文档所述:

如果收到 SocketException,请使用SocketException.ErrorCode 属性获取具体的错误代码。获取此代码后,请参考Windows Sockets version 2 API错误代码文档,了解错误的详细说明。

大多数时候问题是由代码引发的,但在某些情况下,是由网络触发的异常,但是根据您共享的信息,无法知道客户端和服务器之间的问题是什么.

在您分享错误代码后,我可能会帮助您找出问题的原因。

告诉我,你什么时候会发现错误代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-04-10
    • 2020-10-12
    • 1970-01-01
    • 1970-01-01
    • 2021-03-31
    • 2021-12-28
    • 2011-03-13
    • 2016-12-21
    相关资源
    最近更新 更多