Example tested with SnmpSharpNet version 0.7.3.
This example shows how to use Socket class with async receive functionality in a WinForms GUI application without network
causing negative impact on GUI operation. This example will correctly parse and display information in SNMPv1-TRAP, SNMPV2-TRAP
and SNMPV2-INFORM format.
Critical methods in this example are Socket.BeginReceiveFrom(), Socket.EndReceiveFrom()
Example is a very simple application containing a check box (displayed as on/off button) that allows users to enable or disable
SNMP trap/inform reception and a list box that dumps trap, inform and error information.
using System; using System.Windows.Forms; using System.Net; using System.Net.Sockets; using SnmpSharpNet; namespace AsyncTrapReceiver { public class Form1 : Form { protected Socket _socket; protected byte[] _inbuffer; protected IPEndPoint _peerIP; private System.Windows.Forms.ListBox listBox1; private System.Windows.Forms.CheckBox startCheckBox; public Form1 () { // it is not neccessary to initialize variables to null, but better safe then sorry _socket = null; this.listBox1 = new System.Windows.Forms.ListBox (); this.startCheckBox = new System.Windows.Forms.CheckBox (); this.SuspendLayout (); // // listBox1 // this.listBox1.Anchor = ((System.Windows.Forms.AnchorStyles) ((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom) | System.Windows.Forms.AnchorStyles.Left) | System.Windows.Forms.AnchorStyles.Right))); this.listBox1.FormattingEnabled = true; this.listBox1.Location = new System.Drawing.Point (13, 13); this.listBox1.Name = "listBox1"; this.listBox1.Size = new System.Drawing.Size (328, 368); this.listBox1.TabIndex = 0; // // startCheckBox // this.startCheckBox.Anchor = ((System.Windows.Forms.AnchorStyles) ((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right))); this.startCheckBox.Appearance = System.Windows.Forms.Appearance.Button; this.startCheckBox.Location = new System.Drawing.Point (347, 12); this.startCheckBox.Name = "startCheckBox"; this.startCheckBox.Size = new System.Drawing.Size (75, 24); this.startCheckBox.TabIndex = 3; this.startCheckBox.Text = "&Start"; this.startCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter; this.startCheckBox.UseVisualStyleBackColor = true; this.startCheckBox.CheckedChanged += new System.EventHandler (this.onStartChanged); // // Form1 // this.AutoScaleDimensions = new System.Drawing.SizeF (6f, 13f); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; this.ClientSize = new System.Drawing.Size (434, 391); this.Controls.Add (this.startCheckBox); this.Controls.Add (this.listBox1); this.Name = "Form1"; this.Text = "Form1"; this.ResumeLayout (false); } public bool InitializeReceiver () { if (_socket != null) { StopReceiver (); } try { // create an IP/UDP socket _socket = new Socket (AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp); } catch (Exception ex) { listBox1.Items.Add ("SNMP trap receiver socket initialization failed with error: " + ex.Message); // there is no need to close the socket because it was never correctly created _socket = null; } if (_socket == null) return false; try { // prepare to "bind" the socket to the local port number // binding notifies the operating system that application // wishes to receive data sent to the specified port number // prepare EndPoint that will bind the application to all available //IP addresses and port 162 (snmp-trap) EndPoint localEP = new IPEndPoint (IPAddress.Any, 162); // bind socket _socket.Bind (localEP); } catch (Exception ex) { listBox1.Items.Add ("SNMP trap receiver initialization failed with error: " + ex.Message); _socket.Close (); _socket = null; } if (_socket == null) return false; if (!RegisterReceiveOperation ()) return false; return true; } public void StopReceiver () { if (_socket != null) { _socket.Close (); _socket = null; } } public bool RegisterReceiveOperation () { if (_socket == null) return false; // socket has been closed try { _peerIP = new IPEndPoint (IPAddress.Any, 0); // receive from anybody EndPoint ep = (EndPoint)_peerIP; _inbuffer = new byte[64 * 1024]; // nice and big receive buffer _socket.BeginReceiveFrom (_inbuffer, 0, 64 * 1024, SocketFlags.None, ref ep, new AsyncCallback (ReceiveCallback), _socket); } catch (Exception ex) { listBox1.Items.Add ("Registering receive operation failed with message: " + ex.Message); _socket.Close (); _socket = null; } if (_socket == null) return false; return true; } private void ReceiveCallback (IAsyncResult result) { // get a reference to the socket. This is handy if socket has been closed elsewhere in the class Socket sock = (Socket)result.AsyncState; _peerIP = new IPEndPoint (IPAddress.Any, 0); // variable to store received data length int inlen; try { EndPoint ep = (EndPoint)_peerIP; inlen = sock.EndReceiveFrom (result, ref ep); _peerIP = (IPEndPoint)ep; } catch (Exception ex) { // only post messages if class socket reference is not null // in all other cases, user has terminated the socket if (_socket != null) { PostAsyncMessage ("Receive operation failed with message: " + ex.Message); } inlen = -1; } // if socket has been closed, ignore received data and return if (_socket == null) return; // check that received data is long enough if (inlen <= 0) { // request next packet RegisterReceiveOperation (); return; } int packetVersion = SnmpPacket.GetProtocolVersion (_inbuffer, inlen); if (packetVersion == (int)SnmpVersion.Ver1) { SnmpV1TrapPacket pkt = new SnmpV1TrapPacket (); try { pkt.decode (_inbuffer, inlen); } catch (Exception ex) { PostAsyncMessage ("Error parsing SNMPv1 Trap: " + ex.Message); pkt = null; } if (pkt != null) { PostAsyncMessage (String.Format ("** SNMPv1 TRAP from {0}", _peerIP.ToString ())); PostAsyncMessage ( String.Format ("*** community {0} generic id: {1} specific id: {2}", pkt.Community, pkt.Pdu.Generic, pkt.Pdu.Specific) ); PostAsyncMessage (String.Format ("*** PDU count: {0}", pkt.Pdu.VbCount)); foreach (Vb vb in pkt.Pdu.VbList) { PostAsyncMessage ( String.Format ("**** Vb oid: {0} type: {1} value: {2}", vb.Oid.ToString (), SnmpConstants.GetTypeName (vb.Value.Type), vb.Value.ToString ()) ); } PostAsyncMessage ("** End of SNMPv1 TRAP"); } } else if (packetVersion == (int)SnmpVersion.Ver2) { SnmpV2Packet pkt = new SnmpV2Packet (); try { pkt.decode (_inbuffer, inlen); } catch (Exception ex) { PostAsyncMessage ("Error parsing SNMPv1 Trap: " + ex.Message); pkt = null; } if (pkt != null) { if (pkt.Pdu.Type == PduType.V2Trap) { PostAsyncMessage (String.Format ("** SNMPv2 TRAP from {0}", _peerIP.ToString ())); } else if (pkt.Pdu.Type == PduType.Inform) { PostAsyncMessage (String.Format ("** SNMPv2 INFORM from {0}", _peerIP.ToString ())); } else { PostAsyncMessage (String.Format ("Invalid SNMPv2 packet from {0}", _peerIP.ToString ())); pkt = null; } if (pkt != null) { PostAsyncMessage ( String.Format ("*** community {0} sysUpTime: {1} trapObjectID: {2}", pkt.Community, pkt.Pdu.TrapSysUpTime.ToString (), pkt.Pdu.TrapObjectID.ToString ()) ); PostAsyncMessage (String.Format ("*** PDU count: {0}", pkt.Pdu.VbCount)); foreach (Vb vb in pkt.Pdu.VbList) { PostAsyncMessage ( String.Format ("**** Vb oid: {0} type: {1} value: {2}", vb.Oid.ToString (), SnmpConstants.GetTypeName (vb.Value.Type), vb.Value.ToString ()) ); } if (pkt.Pdu.Type == PduType.V2Trap) PostAsyncMessage ("** End of SNMPv2 TRAP"); else { PostAsyncMessage ("** End of SNMPv2 INFORM"); // send ACK back to the INFORM sender SnmpV2Packet response = pkt.BuildInformResponse (); byte[] buf = response.encode (); _socket.SendTo (buf, (EndPoint)_peerIP); } } } } RegisterReceiveOperation (); } protected delegate void PostAsyncMessageDelegate (string msg); protected void PostAsyncMessage (string msg) { if (InvokeRequired) Invoke (new PostAsyncMessageDelegate (PostAsyncMessage), new object[] { msg }); else listBox1.Items.Add (msg); } private void onStartChanged (object sender, EventArgs e) { if (startCheckBox.Checked) { if (!InitializeReceiver ()) { // unable to start TRAP receiver startCheckBox.Checked = false; return; } else { startCheckBox.Text = "S&top"; } } else { StopReceiver (); startCheckBox.Text = "&Start"; } } } } |
Same thing in VB.Net
Imports System Imports System.Windows.Forms Imports System.Net Imports System.Net.Sockets Imports SnmpSharpNet Public Class Form1 Inherits Form Dim _socket As Socket Dim _inbuffer() As Byte Dim _peerIP As IPEndPoint Dim listBox1 As System.Windows.Forms.ListBox Dim WithEvents startCheckBox As System.Windows.Forms.CheckBox Public Sub New() System.Diagnostics.Debug.WriteLine("OnLoad event") _socket = Nothing listBox1 = New System.Windows.Forms.ListBox() startCheckBox = New System.Windows.Forms.CheckBox() SuspendLayout() ' ' listBox1 ' listBox1.Parent = Me listBox1.Anchor = ((((System.Windows.Forms.AnchorStyles.Top Or _ System.Windows.Forms.AnchorStyles.Bottom) Or _ System.Windows.Forms.AnchorStyles.Left) Or _ System.Windows.Forms.AnchorStyles.Right)) listBox1.FormattingEnabled = True listBox1.Location = New System.Drawing.Point(13, 13) listBox1.Name = "listBox1" listBox1.Size = New System.Drawing.Size(328, 368) listBox1.TabIndex = 0 ' ' startCheckBox ' startCheckBox.Parent = Me startCheckBox.Anchor = (System.Windows.Forms.AnchorStyles.Top Or _ System.Windows.Forms.AnchorStyles.Right) startCheckBox.Appearance = System.Windows.Forms.Appearance.Button startCheckBox.Location = New System.Drawing.Point(347, 12) startCheckBox.Name = "startCheckBox" startCheckBox.Size = New System.Drawing.Size(75, 24) startCheckBox.TabIndex = 3 startCheckBox.Text = "&Start" startCheckBox.TextAlign = System.Drawing.ContentAlignment.MiddleCenter startCheckBox.UseVisualStyleBackColor = True ' ' Form1 ' AutoScaleDimensions = New System.Drawing.SizeF(6.0F, 13.0F) AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font ClientSize = New System.Drawing.Size(434, 391) Me.Controls.Add(startCheckBox) Me.Controls.Add(listBox1) Name = "Form1" Text = "Form1" ResumeLayout(False) End Sub Public Function InitializeReceiver() As Boolean If _socket IsNot Nothing Then StopReceiver() End If Try _socket = New Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp) Catch ex As Exception listBox1.Items.Add("SNMP trap receiver socket initialization failed with error: " & ex.Message) ' there is no need to close the socket because it was never correctly created _socket = Nothing Return False End Try Try Dim ep As EndPoint = New IPEndPoint(System.Net.IPAddress.Any, 162) _socket.Bind(ep) Catch ex As Exception listBox1.Items.Add("SNMP trap receiver initialization failed with error: " & ex.Message) _socket.Close() _socket = Nothing Return False End Try If RegisterReceiveOperation() = False Then Return False End If Return True End Function Public Sub StopReceiver() If _socket IsNot Nothing Then _socket.Close() _socket = Nothing End If End Sub Public Function RegisterReceiveOperation() As Boolean If _socket Is Nothing Then Return False End If Try _peerIP = New IPEndPoint(System.Net.IPAddress.Any, 0) ' receive from anybody _inbuffer = New [Byte](64 * 1024) {} ' nice and big receive buffer _socket.BeginReceiveFrom(_inbuffer, 0, _inbuffer.Length, _ System.Net.Sockets.SocketFlags.None, _ _peerIP, New AsyncCallback(AddressOf ReceiveCallback), _socket) Catch ex As Exception listBox1.Items.Add("Registering receive operation failed with message: " & ex.Message) _socket.Close() _socket = Nothing Return False End Try Return True End Function Public Sub ReceiveCallback(ByVal result As IAsyncResult) Dim sock As Socket = result.AsyncState Dim inlen As Integer _peerIP = New IPEndPoint(System.Net.IPAddress.Any, 0) Try inlen = sock.EndReceiveFrom(result, _peerIP) Catch ex As Exception ' only post messages if class socket reference is not null ' in all other cases, user has terminated the socket If _socket IsNot Nothing Then PostAsyncMessage("Receive operation failed with message: " & ex.Message) End If inlen = -1 End Try ' if socket has been closed, don't process received data If _socket IsNot Nothing Then ' check that received data is long enough If inlen > 0 Then Dim packetVersion As Integer = SnmpPacket.GetProtocolVersion(_inbuffer, inlen) If packetVersion = SnmpVersion.Ver1 Then Dim pkt As SnmpV1TrapPacket = New SnmpV1TrapPacket Try pkt.decode(_inbuffer, inlen) Catch ex As Exception PostAsyncMessage("Error parsing SNMPv1 Trap: " + ex.Message) pkt = Nothing End Try If pkt IsNot Nothing Then PostAsyncMessage(String.Format("** SNMPv1 TRAP from {0}", _peerIP.ToString())) PostAsyncMessage(String.Format("*** community {0} generic id: {1} specific id: {2}", _ pkt.Community, pkt.Pdu.Generic, pkt.Pdu.Specific)) PostAsyncMessage(String.Format("*** PDU count: {0}", pkt.Pdu.VbCount)) Dim vb As Vb For Each vb In pkt.Pdu.VbList PostAsyncMessage(String.Format("**** Vb oid: {0} type: {1} value: {2}", _ vb.Oid.ToString(), SnmpConstants.GetTypeName(vb.Value.Type), _ vb.Value.ToString())) Next PostAsyncMessage("** End of SNMPv1 TRAP") End If ElseIf packetVersion = SnmpVersion.Ver2 Then Dim pkt As SnmpV2Packet = New SnmpV2Packet Try pkt.decode(_inbuffer, inlen) Catch ex As Exception pkt = Nothing End Try If pkt.Pdu.Type = PduType.V2Trap Then PostAsyncMessage(String.Format("** SNMPv2 TRAP from {0}", _peerIP.ToString())) ElseIf pkt.Pdu.Type = PduType.Inform Then PostAsyncMessage(String.Format("** SNMPv2 INFORM from {0}", _peerIP.ToString())) Else PostAsyncMessage(String.Format("Invalid SNMPv2 packet from {0}", _peerIP.ToString())) pkt = Nothing End If If pkt IsNot Nothing Then PostAsyncMessage(String.Format("*** community {0} sysUpTime: {1} trapObjectID: {2}", _ pkt.Community, pkt.Pdu.TrapSysUpTime.ToString(), pkt.Pdu.TrapObjectID.ToString())) PostAsyncMessage(String.Format("*** PDU count: {0}", pkt.Pdu.VbCount)) Dim vb As Vb For Each vb In pkt.Pdu.VbList PostAsyncMessage(String.Format("**** Vb oid: {0} type: {1} value: {2}", _ vb.Oid.ToString(), SnmpConstants.GetTypeName(vb.Value.Type), vb.Value.ToString())) Next If pkt.Pdu.Type = PduType.V2Trap Then PostAsyncMessage("** End of SNMPv2 TRAP") Else PostAsyncMessage("** End of SNMPv2 INFORM") ' send ACK back to the INFORM sender Dim response As SnmpV2Packet = pkt.BuildInformResponse() Dim buf() As Byte = response.encode() _socket.SendTo(buf, _peerIP) End If End If End If RegisterReceiveOperation() End If End If End Sub Protected Delegate Sub PostAsyncMessageDelegate(ByVal msg As String) Protected Sub PostAsyncMessage(ByVal msg As String) If InvokeRequired Then Dim param() As Object param = New Object() {msg} Invoke(New PostAsyncMessageDelegate(AddressOf PostAsyncMessage), param) Else listBox1.Items.Add(msg) End If End Sub Private Sub OnStartChanged(ByVal sender As Object, ByVal e As EventArgs) _ Handles startCheckBox.CheckedChanged If startCheckBox.Checked Then If Not InitializeReceiver() Then startCheckBox.Checked = False Else startCheckBox.Text = "S&top" End If Else StopReceiver() startCheckBox.Text = "&Start" End If End Sub End Class |