我在一个Windows服务中有以下类,它遇到了一些不同的奇怪关闭行为。服务器不时关闭,事件日志中只有此消息,跟踪日志中没有消息,“广播服务意外终止。已经做了1次。”
Public Class ServerSocket
Implements IServerSocket
Public Event ClientConnected(ByVal sender As Object, ByVal e As EventArgs(Of IClientSocket)) Implements IServerSocket.ClientConnected
Private _socket As Socket
Private ReadOnly _settings As IBroadcasterServiceSettingsSection
Private ReadOnly _traceSource As ITraceSource
Public Sub New()
Me.New(BroadcasterServiceSettingsSection.GetSection, BroadcasterTraceSource.Instance)
End Sub
Public Sub New(ByVal settings As IBroadcasterServiceSettingsSection, ByVal traceSource As ITraceSource)
_settings = settings
_traceSource = traceSource
End Sub
Public Sub Listen() Implements IServerSocket.Listen
Dim endPoint As New IPEndPoint(System.Net.IPAddress.Parse(_settings.BroadcasterIPAddress), _settings.BroadcasterPortNumber)
Try
_socket = New Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp)
_socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, 1)
_socket.Bind(endPoint)
_socket.Listen(SocketOptionName.MaxConnections)
_socket.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), Nothing)
_traceSource.TraceInformation("ServerSocket listening for new clients.")
Catch ex As Exception
_traceSource.TraceCritical("ServerSocket caughtException trying to wait for a new client.")
Throw ex
End Try
End Sub
''' <summary>
''' First attempts to shutdown the socket to clean up any remaining data left to send or receive. Then closes
''' the socket to release all connections and clean up unmanaged resources. See also <seealso cref="System.Net.Sockets.Socket.Shutdown">Socket.Shutdown</seealso>
''' and <seealso cref="System.Net.Sockets.Socket.Close">Socket.Close</seealso>
''' </summary>
Public Sub Close() Implements IServerSocket.Close
Try
_socket.Shutdown(SocketShutdown.Both)
Catch ex As Exception
_traceSource.TraceEvent(TraceEventType.Error, "Shutting down Server Socket caused an exception.", ex.Message, ex.StackTrace)
End Try
Try
_socket.Close()
Catch ex As Exception
_traceSource.TraceEvent(TraceEventType.Error, "Closing the Server Socket caused an exception.", ex.Message, ex.StackTrace)
End Try
_traceSource.TraceEvent(TraceEventType.Information, "ServerSocket closed.")
End Sub
Private Sub AcceptCallback(ByVal ar As IAsyncResult)
Dim s As Socket = Nothing
Try
s = _socket.EndAccept(ar)
Catch ex As Exception
_traceSource.TraceInformation("ServerSocket caught exception trying to get new socket for client.", ex.Message, ex.StackTrace)
End Try
Try
' call the begin accept as soon as possible so that I can get the next incoming client
_socket.BeginAccept(New AsyncCallback(AddressOf AcceptCallback), Nothing)
Catch ex As Exception
_traceSource.TraceEvent(TraceEventType.Critical, "ServerSocket caughtException trying to wait for a new client.", ex.Message, ex.StackTrace)
End Try
Try
If s IsNot Nothing Then
Dim clientSocket As IClientSocket = New ClientSocket(s)
OnClientConnected(New EventArgs(Of IClientSocket)(clientSocket))
End If
Catch ex As Exception
_traceSource.TraceEvent(TraceEventType.Critical, "9/23 Review: " + ex.ToString())
End Try
End Sub
Private Sub OnClientConnected(ByVal e As EventArgs(Of IClientSocket))
RaiseEvent ClientConnected(Me, e)
End Sub
End Class
这个类的一个突出特点是,在调用了socket.endaccept之后立即调用了socket.beginaccept,然后完成了对“客户机套接字”的工作。我不能把手指放在上面,但这味道不太好。用于侦听新连接的套接字是否应保留为字段?如果不是,你以后怎么叫关机?这是一个非常长的运行(周/月)过程。