У меня есть следующий класс в службе Windows, который испытывает некоторые странные поведения выключения.Сервер время от времени отключается, только в журналах событий появляется только это сообщение, а в журналах трассировки нет сообщений: «Служба Broadcaster неожиданно прервана. Это произошло 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, и после этого работа с «Client Socket» завершается.Я не могу указать на это пальцем, но это просто пахнет неправильно.Должен ли сокет, который используется для прослушивания новых соединений, оставаться полем?Если нет, как бы вы назвали выключение позже?Это очень длительный (недели / месяцы) процесс.