I modified the logmonitor sdk example so it would work over a network. It
works great when the client and server are running on the same PC and have
administrator privileges. So I have two problems:
1) I cannot run the client without administrator privileges. If I try I get
the following message:
Unhandled Exception: System.Security .SecurityExcept ion: Requested registry
access is not allowed.
at System.ThrowHel per.ThrowSecuri tyException(Exc eptionResource resource)
at Microsoft.Win32 .RegistryKey.Op enSubKey(String name, Boolean writable)
at System.Diagnost ics.EventLog.Ex ists(String logName, String machineName)
at LogMonitor_Clie nt.Microsoft.Sa mples.LogMonito r.Main()
The Zone of the assembly that failed was:
MyComputer
I have a try catch in the client so I don't know what the problem is. What
am I doing wrong?
2) My server crashes when a remote client disconnects. Here is its message:
Unhandled Exception: System.Net.Sock ets.SocketExcep tion: An existing
connection was forcibly closed by the remote host
at System.Net.Sock ets.Socket.Begi nReceive(Byte[] buffer, Int32 offset,
Int32size, SocketFlags socketFlags, syncCallback callback, Object state)
at LogMonitor_Serv er.Module1.Acce ptCallback(IAsy ncResult ar)
at System.Net.Lazy AsyncResult.Com plete(IntPtr userToken)
at System.Net.Cont extAwareResult. CaptureOrComple te(ExecutionCon text&
cachedContext, Boolean returnContext)
at System.Net.Cont extAwareResult. FinishPostingAs yncOp(CallbackC losure&
closure)
at System.Net.Sock ets.Socket.Begi nAccept(AsyncCa llback callback, Object
state)
at LogMonitor_Serv er.Module1.Main ()
I don't know why the server always crashes when a remote client leaves. If
I run the client and server on the same machine and have the client leave
the server stays running. What am I doing wrong?
Thanks,
Here is the client:
Public Class StateObject
Public workSocket As System.Net.Sock ets.Socket = Nothing
Public Const BufferSize As Integer = 256
Public buffer(BufferSi ze) As Byte
Public sb As New System.Text.Str ingBuilder
End Class
Namespace Microsoft.Sampl es
Module LogMonitor
Dim WithEvents evtApp As New EventLog("Appli cation")
Dim WithEvents evtSys As New EventLog("Syste m")
Dim WithEvents evtSec As New EventLog("Secur ity")
Private connectDone As New System.Threadin g.ManualResetEv ent(False)
Private sendDone As New System.Threadin g.ManualResetEv ent(False)
Private receiveDone As New System.Threadin g.ManualResetEv ent(False)
Private response As String = String.Empty
Public Sub Main()
If (Not EventLog.Exists ("system", ".")) Then
MsgBox("The sytem log does not exist!", , "Error")
Exit Sub
End If
If (Not EventLog.Exists ("applicatio n", ".")) Then
MsgBox("The application log does not exist!", , "Error")
Exit Sub
End If
If (Not EventLog.Exists ("security", ".")) Then
MsgBox("The security log does not exist!", , "Error")
Exit Sub
End If
evtApp.MachineN ame = System.Net.Dns. GetHostName
evtSys.MachineN ame = System.Net.Dns. GetHostName
evtSec.MachineN ame = System.Net.Dns. GetHostName
AddHandler evtApp.EntryWri tten, AddressOf OnEntryWritten
evtApp.EnableRa isingEvents = True
AddHandler evtSys.EntryWri tten, AddressOf OnEntryWritten
evtSys.EnableRa isingEvents = True
AddHandler evtSec.EntryWri tten, AddressOf OnEntryWritten
evtSec.EnableRa isingEvents = True
While (Console.Read() <> 113)
System.Threadin g.Thread.Sleep( 14500)
End While
End Sub
Sub OnEntryWritten( ByVal source As Object, ByVal e As EntryWrittenEve ntArgs)
Handles evtApp.EntryWri tten, evtSec.EntryWri tten, evtSys.EntryWri tten
Dim checkinfo As String
Dim checkwarn As String
Dim checkerror As String
Dim checksucc As String
Dim checkfail As String
Dim checkserver As String
Dim checkport As String
Try
checkinfo =
My.Computer.Reg istry.GetValue( "HKEY_LOCAL_MAC HINE\Software\D ravet", "info",
Nothing)
checkwarn =
My.Computer.Reg istry.GetValue( "HKEY_LOCAL_MAC HINE\Software\D ravet", "warn",
Nothing)
checkerror =
My.Computer.Reg istry.GetValue( "HKEY_LOCAL_MAC HINE\Software\D ravet", "error",
Nothing)
checksucc =
My.Computer.Reg istry.GetValue( "HKEY_LOCAL_MAC HINE\Software\D ravet", "succ",
Nothing)
checkfail =
My.Computer.Reg istry.GetValue( "HKEY_LOCAL_MAC HINE\Software\D ravet", "fail",
Nothing)
checkserver =
My.Computer.Reg istry.GetValue( "HKEY_LOCAL_MAC HINE\Software\D ravet",
"server", Nothing)
checkport =
My.Computer.Reg istry.GetValue( "HKEY_LOCAL_MAC HINE\Software\D ravet",
"portnum", Nothing)
If (checkinfo.ToUp per = "TRUE") And (e.Entry.EntryT ype =
EventLogEntryTy pe.Information) Then
sendinfo(e, checkserver, checkport)
Exit Sub
End If
If (checkwarn.ToUp per = "TRUE") And (e.Entry.EntryT ype =
EventLogEntryTy pe.Warning) Then
sendinfo(e, checkserver, checkport)
Exit Sub
End If
If (checkerror.ToU pper = "TRUE") And (e.Entry.EntryT ype =
EventLogEntryTy pe.Error) Then
sendinfo(e, checkserver, checkport)
Exit Sub
End If
If (checksucc.ToUp per = "TRUE") And (e.Entry.EntryT ype =
EventLogEntryTy pe.SuccessAudit ) Then
sendinfo(e, checkserver, checkport)
Exit Sub
End If
If (checkfail.ToUp per = "TRUE") And (e.Entry.EntryT ype =
EventLogEntryTy pe.FailureAudit ) Then
sendinfo(e, checkserver, checkport)
Exit Sub
End If
Catch se As System.Security .SecurityExcept ion
Catch se2 As System.Unauthor izedAccessExcep tion
MsgBox("A Security Exception has occurred", , "LogMonitor Error")
End Try
End Sub
Sub sendinfo(ByVal e As EntryWrittenEve ntArgs, ByVal servername As String,
ByVal portnum As String)
Dim sendbuffer As String
Dim ipHostInfo As System.Net.IPHo stEntry =
System.Net.Dns. GetHostEntry(se rvername)
Dim ipAddress As System.Net.IPAd dress = ipHostInfo.Addr essList(0)
Dim remoteEP As New System.Net.IPEn dPoint(ipAddres s, portnum)
Dim client As New
System.Net.Sock ets.Socket(Syst em.Net.Sockets. AddressFamily.I nterNetwork,
System.Net.Sock ets.SocketType. Stream, System.Net.Sock ets.ProtocolTyp e.Tcp)
Dim hostname As String = System.Net.Dns. GetHostName()
client.BeginCon nect(remoteEP, New AsyncCallback(A ddressOf ConnectCallback ),
client)
connectDone.Wai tOne()
sendbuffer = hostname & "<BREAK>" & e.Entry.Message & "<EOF>"
Send(client, sendbuffer)
sendDone.WaitOn e()
client.Shutdown (System.Net.Soc kets.SocketShut down.Both)
client.Close()
End Sub
Private Sub ConnectCallback (ByVal ar As IAsyncResult)
Dim client As System.Net.Sock ets.Socket = CType(ar.AsyncS tate,
System.Net.Sock ets.Socket)
client.EndConne ct(ar)
connectDone.Set ()
End Sub
Private Sub Receive(ByVal client As System.Net.Sock ets.Socket)
Dim state As New StateObject
state.workSocke t = client
client.BeginRec eive(state.buff er, 0, StateObject.Buf ferSize, 0, New
AsyncCallback(A ddressOf ReceiveCallback ), state)
End Sub
Private Sub ReceiveCallback (ByVal ar As IAsyncResult)
Dim state As StateObject = CType(ar.AsyncS tate, StateObject)
Dim client As System.Net.Sock ets.Socket = state.workSocke t
Dim bytesRead As Integer = client.EndRecei ve(ar)
If bytesRead > 0 Then
' There might be more data, so store the data received so far.
state.sb.Append (System.Text.En coding.ASCII.Ge tString(state.b uffer, 0,
bytesRead))
' Get the rest of the data.
client.BeginRec eive(state.buff er, 0, StateObject.Buf ferSize, 0, New
AsyncCallback(A ddressOf ReceiveCallback ), state)
Else
' All the data has arrived; put it in response.
If state.sb.Length > 1 Then
response = state.sb.ToStri ng()
End If
receiveDone.Set ()
End If
End Sub
Private Sub Send(ByVal client As System.Net.Sock ets.Socket, ByVal data As
String)
Dim byteData As Byte() = System.Text.Enc oding.ASCII.Get Bytes(data)
client.BeginSen d(byteData, 0, byteData.Length , 0, New
AsyncCallback(A ddressOf SendCallback), client)
End Sub
Private Sub SendCallback(By Val ar As IAsyncResult)
Dim client As System.Net.Sock ets.Socket = CType(ar.AsyncS tate,
System.Net.Sock ets.Socket)
Dim bytesSent As Integer = client.EndSend( ar)
sendDone.Set()
End Sub
End Module
End Namespace
SERVER ----------------------------------------------------------------------------
Public Class StateObject
Public workSocket As System.Net.Sock ets.Socket = Nothing
Public Const BufferSize As Integer = 1024
Public buffer(BufferSi ze) As Byte
Public sb As New System.Text.Str ingBuilder
End Class
Module Module1
Dim portnum As String
Dim SBuffer(4096) As Byte
Dim SBytes As Integer
Public allDone As New System.Threadin g.ManualResetEv ent(False)
Sub Main()
Dim args As String()
args = Environment.Get CommandLineArgs ()
portnum = args(1)
If Not IsNumeric(portn um) Then
Console.WriteLi ne("Usage: LogMonitor.exe portnumber")
Console.WriteLi ne()
Console.WriteLi ne("Press Enter to continue...")
Console.ReadLin e()
Exit Sub
End If
If (args.Length <> 2) Then
Console.WriteLi ne("Usage: LogMonitor.exe portnumber")
Console.WriteLi ne()
Console.WriteLi ne("Press Enter to continue...")
Console.ReadLin e()
Exit Sub
End If
Dim theIPEndPoint As System.Net.IPEn dPoint = New
System.Net.IPEn dPoint(System.N et.IPAddress.An y, portnum)
Dim ServerSocket As System.Net.Sock ets.Socket = New
System.Net.Sock ets.Socket(Net. Sockets.Address Family.InterNet work,
Net.Sockets.Soc ketType.Stream, Net.Sockets.Pro tocolType.Tcp)
ServerSocket.Bl ocking = True
ServerSocket.Bi nd(theIPEndPoin t)
ServerSocket.Li sten(10)
While True
allDone.Reset()
Console.WriteLi ne("Waiting for a connection...")
ServerSocket.Be ginAccept(New AsyncCallback(A ddressOf
AcceptCallback) , ServerSocket)
allDone.WaitOne ()
End While
End Sub
Public Sub AcceptCallback( ByVal ar As IAsyncResult)
Dim listener As System.Net.Sock ets.Socket = CType(ar.AsyncS tate,
System.Net.Sock ets.Socket)
Dim handler As System.Net.Sock ets.Socket = listener.EndAcc ept(ar)
Dim state As New StateObject
state.workSocke t = handler
handler.BeginRe ceive(state.buf fer, 0, StateObject.Buf ferSize, 0, New
AsyncCallback(A ddressOf ReadCallback), state)
End Sub
Public Sub ReadCallback(By Val ar As IAsyncResult)
Dim content As String = String.Empty
Dim state As StateObject = CType(ar.AsyncS tate, StateObject)
Dim handler As System.Net.Sock ets.Socket = state.workSocke t
Dim bytesRead As Integer = handler.EndRece ive(ar)
Dim dotposition As Integer
Dim buffer As String
Dim hostname As String
If bytesRead > 0 Then
' There might be more data, so store the data received so far.
state.sb.Append (System.Text.En coding.ASCII.Ge tString(state.b uffer,
0, bytesRead))
' Check for end-of-file tag. If it is not there, read more data.
content = state.sb.ToStri ng()
If content.IndexOf ("<EOF>") > -1 Then
' All the data has been read from the client. Display it on the
console.
dotposition = InStr(content, "<BREAK>") - 1
hostname = Left(content, dotposition)
buffer = Replace(content , "<EOF>", "")
buffer = Right(buffer, buffer.Length - hostname.Length - 7)
MsgBox(buffer, , "Eventlog Alert from " & hostname)
' Echo the data back to the client.
Send(handler, content)
Else
' Not all data received. Get more.
handler.BeginRe ceive(state.buf fer, 0, StateObject.Buf ferSize, 0,
New AsyncCallback(A ddressOf ReadCallback), state)
End If
End If
End Sub
Private Sub Send(ByVal handler As System.Net.Sock ets.Socket, ByVal data As
String)
Dim byteData As Byte() = System.Text.Enc oding.ASCII.Get Bytes(data)
handler.BeginSe nd(byteData, 0, byteData.Length , 0, New
AsyncCallback(A ddressOf SendCallback), handler)
End Sub
Private Sub SendCallback(By Val ar As IAsyncResult)
Dim handler As System.Net.Sock ets.Socket = CType(ar.AsyncS tate,
System.Net.Sock ets.Socket)
Dim bytesSent As Integer = handler.EndSend (ar)
Console.WriteLi ne("Sent {0} bytes to client.", bytesSent)
handler.Shutdow n(System.Net.So ckets.SocketShu tdown.Both)
handler.Close()
allDone.Set()
End Sub
End Module