套接字服务器问题:套接字服务器崩溃

问题描述

我们有一个 .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,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.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,System.Threading.NativeOverlapped*)

先谢谢你:)

解决方法

Simali,欢迎来到 Stackoverflow。

首先,当您发布问题时,要求将代码发布到您的问题而不是评论中。 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,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,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。所以我建议你检查异步套接字抛出的所有可能的异常并处理它们。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...