Problem handling multiple ICMP pings responses

fabianCastle

New member
Joined
Mar 4, 2005
Messages
2
Programming Experience
Beginner
I'm using threads to send multiple pings simultaneously. I used a pocket sniffer to check that the send and request packages are well formed.

My app creates multiples threads, withing them a ping object is created witch uses a socket to perform the ICMP Ping.

The pings response time and timeouts are just not working.

any suggestions ?

PING class:
--------------------------------------------------------------------------
Option Explicit On
Imports System

Imports System.Net

Imports System.Net.Sockets

'* Class clsPing

'*

'* Author : Paulo S. Silva Jr.

'* Date : September 2002

'* Objective : Ping a host and return basic informations

'*

'* Class Properties

'*

'* +------------+-------------+-------------------------------------------------+

'* | Name | Type | Description |

'* +------------+-------------+-------------------------------------------------+

'* | DataSize | Integer | Size of the data to be send to the host |

'* | Identifier | Integer | Identifier of ping packet |

'* | Sequence | Integer | Sequence of the packet |

'* | LocalHost | IPHostEntry | Info for Local Computer |

'* | TimeOut | Long | Time (in millisecons) of the time-out value |

'* | Host | Object | Host Entry for the remote computer |

'* +------------+-------------+-------------------------------------------------+

'*

'* Class Methods

'*

'* +-------------------+----------------------------------------------------+

'* | Name | Description |

'* +-------------------+----------------------------------------------------+

'* | PingHost | Pings the specified host |

'* +-------------------+----------------------------------------------------+

'*

'* Parts of the code based on information from Visual Studio Magazine

'* more info : http://www.fawcette.com/vsm/2002_03/magazine/columns/qa/default.asp

'*

Public Class clsPing

Public Structure stcError

Dim Number As Integer

Dim Description As String

End Structure

Private Const PING_ERROR_BASE As Long = &H8000

Public Const PING_SUCCESS As Long = 0

Public Const PING_ERROR As Long = (-1)

Public Const PING_ERROR_HOST_NOT_FOUND As Long = PING_ERROR_BASE + 1

Public Const PING_ERROR_SOCKET_DIDNT_SEND As Long = PING_ERROR_BASE + 2

Public Const PING_ERROR_HOST_NOT_RESPONDING As Long = PING_ERROR_BASE + 3

Public Const PING_ERROR_TIME_OUT As Long = PING_ERROR_BASE + 4



Private Const ICMP_ECHO As Integer = 8

Private Const SOCKET_ERROR As Integer = -1

Private udtError As stcError

Private Const intPortICMP As Integer = 7

Private Const intBufferHeaderSize As Integer = 8

Private Const intPackageHeaderSize As Integer = 28

Private byteDataSize As Byte

Private lngTimeOut As Long

Private ipheLocalHost As System.Net.IPHostEntry

Private ipheHost As System.Net.IPHostEntry

Private lngResponeMs As Long

Public Property TimeOut() As Long

Get

Return lngTimeOut

End Get

Set(ByVal Value As Long)

lngTimeOut = Value

End Set

End Property

Public Property DataSize() As Byte

Get

Return byteDataSize

End Get

Set(ByVal Value As Byte)

byteDataSize = Value

End Set

End Property

Public ReadOnly Property Identifier() As Byte

Get

Return 0

End Get

End Property

Public ReadOnly Property responseTime() As Long

Get

Return lngResponeMs

End Get

End Property

Public ReadOnly Property Sequence() As Byte

Get

Return 0

End Get

End Property

Public ReadOnly Property LocalHost() As System.Net.IPHostEntry

Get

Return ipheLocalHost

End Get

End Property

Public Property Host() As Object

Get

Return ipheHost

End Get

Set(ByVal Value As Object)

If (Value.GetType.ToString.ToLower = "system.string") Then

'*

'* Find the Host's IP address

'*

Try

ipheHost = System.Net.Dns.GetHostByName(Value)

Catch

ipheHost = Nothing

udtError.Number = PING_ERROR_HOST_NOT_FOUND

udtError.Description = "Host " & ipheHost.HostName & " not found."

End Try

ElseIf (Value.GetType.ToString.ToLower = "system.net.iphostentry") Then

ipheHost = (Value)

Else

ipheHost = Nothing

End If

End Set

End Property

'*

'* Class Constructor

'*

Public Sub New()

'*

'* Initializes the parameters

'*

byteDataSize = 32

lngTimeOut = 500

udtError =
New stcError()

'*

'* Get local IP and transform in EndPoint

'*

ipheLocalHost = System.Net.Dns.GetHostByName(System.Net.Dns.GetHostName())

'*

'* Defines Host

'*

ipheHost = Nothing

End Sub

'*

'* Function : PingHost

'* Author : Paulo dos Santos Silva Jr

'* Date : 05/09/2002

'* Objective : Pings a specified host

'*

'* Parameters : Host as String

'*

'* Returns : Response time in milliseconds

'* (-1) if error

'*

Public Function Ping() As Long

Dim intCount As Integer

Dim aReplyBuffer(255) As Byte

Dim intNBytes As Integer = 0

Dim intEnd As Integer

Dim intStart As Integer

Dim epFrom As System.Net.EndPoint

Dim epServer As System.Net.EndPoint

Dim ipepServer As System.Net.IPEndPoint

lngResponeMs = -1

'*

'* Transforms the IP address in EndPoint

'*

ipepServer = New System.Net.IPEndPoint(ipheHost.AddressList(0), 0)

epServer =
CType(ipepServer, System.Net.EndPoint)

epFrom =
New System.Net.IPEndPoint(ipheLocalHost.AddressList(0), 0)

'*

'* Builds the packet to send

'*

DataSize = Convert.ToByte(DataSize + intBufferHeaderSize)

'*

'* The packet must by an even number, so if the DataSize is and odd number adds one

'*

If (DataSize Mod 2 = 1) Then

DataSize += Convert.ToByte(1)

End If

Dim aRequestBuffer(DataSize - 1) As Byte

'*

'* --- ICMP Echo Header Format ---

'* (first 8 bytes of the data buffer)

'*

'* Buffer (0) ICMP Type Field

'* Buffer (1) ICMP Code Field

'* (must be 0 for Echo and Echo Reply)

'* Buffer (2) checksum hi

'* (must be 0 before checksum calc)

'* Buffer (3) checksum lo

'* (must be 0 before checksum calc)

'* Buffer (4) ID hi

'* Buffer (5) ID lo

'* Buffer (6) sequence hi

'* Buffer (7) sequence lo

'* Buffer (8)..(n) Ping Data

'*

'*

'* Set Type Field

'*

aRequestBuffer(0) = Convert.ToByte(8) ' ECHO Request

'*

'* Set ID field

'*

BitConverter.GetBytes(Identifier).CopyTo(aRequestBuffer, 4)

'*

'* Set Sequence

'*

BitConverter.GetBytes(Sequence).CopyTo(aRequestBuffer, 6)

'*

'* Load some data into buffer

'*

Dim i As Integer

For i = 8 To DataSize - 1

aRequestBuffer(i) = Convert.ToByte(i
Mod 8)

Next i

'*

'* Calculate Checksum

'*

Call CreateChecksum(aRequestBuffer, DataSize, aRequestBuffer(2), aRequestBuffer(3))



'*

'* Try send the packet

'*

Try

'*

'* Create the socket

'*

Dim sckSocket As New System.Net.Sockets.Socket( _

Net.Sockets.AddressFamily.InterNetwork, _

Net.Sockets.SocketType.Raw, _

Net.Sockets.ProtocolType.Icmp)

sckSocket.Blocking =
False

'*

'* Sends Package

'*

sckSocket.SendTo(aRequestBuffer, 0, DataSize, SocketFlags.None, ipepServer)



'*

'* Records the Start Time, after sending the Echo Request

'*

intStart = System.Environment.TickCount

'*

'* Waits for response

'*

Do

'Application.DoEvents()

Try

intNBytes = sckSocket.ReceiveFrom(aReplyBuffer, SocketFlags.None, epServer)

Catch objErr As Exception

End Try

Loop Until (intNBytes > 0) Or ((System.Environment.TickCount - intStart) > TimeOut)

sckSocket =
Nothing

'*

'* Check to see if the TimeOut was hit

'*

If ((System.Environment.TickCount - intStart) > TimeOut) Then

udtError.Number = PING_ERROR_TIME_OUT

udtError.Description = "Time Out"

Return (PING_ERROR)

End If

'*

'* Records End Time

'*

intEnd = System.Environment.TickCount

If (intNBytes > 0) Then

'*

'* Informs on GetLastError the state of the server

'*

udtError.Number = (aReplyBuffer(19) * &H100) + aReplyBuffer(20)

Select Case aReplyBuffer(20)

Case 0 : udtError.Description = "Success"

Case 1 : udtError.Description = "Buffer too Small"

Case 2 : udtError.Description = "Destination Unreahable"

Case 3 : udtError.Description = "Dest Host Not Reachable"

Case 4 : udtError.Description = "Dest Protocol Not Reachable"

Case 5 : udtError.Description = "Dest Port Not Reachable"

Case 6 : udtError.Description = "No Resources Available"

Case 7 : udtError.Description = "Bad Option"

Case 8 : udtError.Description = "Hardware Error"

Case 9 : udtError.Description = "Packet too Big"

Case 10 : udtError.Description = "Reqested Timed Out"

Case 11 : udtError.Description = "Bad Request"

Case 12 : udtError.Description = "Bad Route"

Case 13 : udtError.Description = "TTL Exprd In Transit"

Case 14 : udtError.Description = "TTL Exprd Reassemb"

Case 15 : udtError.Description = "Parameter Problem"

Case 16 : udtError.Description = "Source Quench"

Case 17 : udtError.Description = "Option too Big"

Case 18 : udtError.Description = "Bad Destination"

Case 19 : udtError.Description = "Address Deleted"

Case 20 : udtError.Description = "Spec MTU Change"

Case 21 : udtError.Description = "MTU Change"

Case 22 : udtError.Description = "Unload"

Case Else : udtError.Description = "General Failure"

End Select

End If

lngResponeMs = (intEnd - intStart)

Return (intEnd - intStart)

Catch oExcept As Exception

'

End Try

End Function

Public Function GetLastError() As stcError

Return udtError

End Function

' ICMP requires a checksum that is the one's

' complement of the one's complement sum of

' all the 16-bit values in the data in the

' buffer.

' Use this procedure to load the Checksum

' field of the buffer.

' The Checksum Field (hi and lo bytes) must be

' zero before calling this procedure.

Private Sub CreateChecksum(ByRef data() As Byte, ByVal Size As Integer, ByRef HiByte As Byte, ByRef LoByte As Byte)

Dim i As Integer

Dim chk As Integer = 0

For i = 0 To Size - 1 Step 2

chk += Convert.ToInt32(data(i) * &H100 + data(i + 1))

Next

chk = Convert.ToInt32((chk And &HFFFF&) + Fix(chk / &H10000&))

chk += Convert.ToInt32(Fix(chk / &H10000&))

chk =
Not (chk)

HiByte = Convert.ToByte((chk
And &HFF00) / &H100)

LoByte = Convert.ToByte(chk
And &HFF)

End Sub

End
Class


Test Class with Trhead:
-----------------------------

Imports System.Threading.Thread

Imports System.Threading.ThreadState



Public Class clsTest

Dim MyThread As New System.Threading.Thread(AddressOf execute)



Public timerInterval As Long

Public bContinueRunning As Boolean

Public id As Long

Public ip As String

Public txtLog As Object

Public lstView As ListView

Public Sub New()

timerInterval = 60000 * 2
' 2 mins.

bContinueRunning = False

ip = ""

End Sub

Private Sub execute()

While bContinueRunning = True



Dim status As String

Dim iResponse As Long

'Dim oPing As New icmpPing.clsPing()

Dim oPing As New clsPing()



txtLog.text = lstView.Items(id).SubItems(3).Text()

oPing.Host = lstView.Items(id).SubItems(3).Text()

oPing.TimeOut = 2000

oPing.DataSize = 32

iResponse = oPing.Ping()

'*

'* Check for error

'*

If (iResponse < 0) Then

lstView.Items(id).SubItems(5).Text() = "-1"

Else

lstView.Items(id).SubItems(5).Text() = oPing.responseTime

End If

status = oPing.GetLastError().Description

lstView.Items(id).SubItems(1).Text() = status

lstView.Items(id).SubItems(4).Text() = Val(lstView.Items(id).SubItems(4).Text()) + 1

lstView.Items(id).SubItems(6).Text() = Now.ToString

oPing =
Nothing

If bContinueRunning = True Then MyThread.Sleep(timerInterval)

End While

'slepp timerInterval

End Sub

Public Sub startTest()

If MyThread.ThreadState = Unstarted Then

MyThread.Start()

Else

MyThread.Resume()

End If

bContinueRunning = True

End Sub

Public Sub stopTest()

bContinueRunning =
False

MyThread.Suspend()

End Sub

Public Sub execTest()

execute()

End Sub



Protected Overrides Sub Finalize()

MyBase.Finalize()

MyThread.Abort()

MyThread =
Nothing

End Sub

End
Class

 
Back
Top