![Scanner-library-in-windows8.gif]()
 
Now that we have an address and subnet, we know exactly what we can do as far as 
pinging. The next step is to actually start the ping. 
We can define a ping as follows:
Dim 
png As New 
Net.NetworkInformation.Ping
The Ping.Send method has several 
overloaded methods but the one that we will use here is Ping.Send(IPAddress). 
All send methods return a PingReply structure which contains the address and 
round trip time. So we can send a ping and get a reply which can then be 
analyzed.
PingReply = 
png.Send(PingAddress) ' ping the IP and capture the 
responce
From the address we can then 
determine the node name like so:
       
Dim IpToDomainName 
As IPHostEntry = Dns.GetHostEntry(IP)
        'return information about a particular 
address
      Return (IpToDomainName.HostName)
' the name of that node is in that info
Putting all that together we get the following code snippet.
       
Static row As
Long
        Dim pr
As PingReply ' 
pinging an address returns a structure called ping reply
        Dim ComputerName
As String =
""
        Timer1.Enabled = False
' since we are doing this periodically on a timer, 
just disable the timer while we are in here to prevent re-entry
        ' turn the timer back on when we 
leave. This ensures the fastest turn around
        If DataGridView1.ColumnCount < 
3 Then ' 
initialize the colums of the grid view
            DataGridView1.Columns.Add("Column1",
"IP")
            DataGridView1.Columns.Add("Column1",
"Time")
            DataGridView1.Columns.Add("Column1",
"Name")
        End If
       
If txtIP.Text <>
"" Then
' if there is an IP selected
            If PingAddress =
"" Then
' if the ping address is empty
                PingAddress = txtIP.Text ' 
fill it from the text box otherwise just ping the address in the box (for 
inrementing the address
                If
Not FindAddressBytes()
Then ' convert the 
IP address into a four byte array
                    Exit
Sub 'if that 
didn't work . . .  give up
                End
If
            End
If
        Else
            PingAddress = ""
        End 
If
        Try
            ToolStripStatusLabel2.Text =
"initializing"
' inform the user
            RebuildPingAddress() ' this 
reconverts the address from four byte array back to a string (after we have 
automatically incremented it
            txtIP.Text = PingAddress ' show 
the user where we are
            ' we are now ready to send a ping 
to see if anyone is home
            'Dim png As New 
Net.NetworkInformation.Ping
            pr = png.Send(PingAddress) ' ping 
the IP and capture the responce
            ToolStripStatusLabel2.Text =
"pinging " & PingAddress
            If pr.Status = IPStatus.Success
Then ' if the 
responce was good
                DataGridView1.Rows.Add() ' we 
should add a new row to the grid view
                DataGridView1.Rows(row).Cells(0).Value = pr.Address
' and fill that row in with address
                DataGridView1.Rows(row).Cells(1).Value = 
pr.RoundtripTime.ToString & " ms"
' round trip time
                ' we should now show the name 
of the device / computer at that address
                ComputerName = DoGetHostEntry(pr.Address.ToString)
                DataGridView1.Rows(row).Cells(2).Value = ComputerName
' display that nodes name
                'b = pr.Buffer ' the buffer 
contains the returned data from the ping (most often just a series of bytes
                If
Not active Then
' allow the user to cancel
                    ToolStripStatusLabel2.Text =
"User Canceled"
                    Exit
Sub
                End 
If
So we have 'pinged' our own address and found that we are there. It didn't take 
all that code to figure that out. What we would like to know is whether or not 
there are others on the same network. That's the same only a different address. 
If we knew all the addresses that were on the network, we would just make a list 
and ping them but we don't. Therefore we must ping all addresses that are within 
the range of our subnet by incrementing the address after each ping. If the ping 
is successful then we add that info to the list and keep going.
Of course 'if it is worth doing, it is worth overdoing . . . we might like to 
see what ports are open and thus vulnerable. This can be done in the 
straightforward / slow manner by trying to open every port from 0 to 65535. If 
it connects then that port is open. If an error occurs that port is not open. 
Opening a port that is available is quite quick. If all ports were open this 
would be fast and furious but any time the port is not open, it takes atleast a 
second to throw an error, So we are looking at more that 65000 seconds to check 
a normal node and there are usually more than one nodes.
I think I just fell asleep thinking about all that waiting . . . excuse me while 
I make some coffee.
If you are only checking a few of the more commonm nodes there is no need to get 
fancy so lets look at the easy way first.
To check to see if a port is open you can use the TCPClient.Connect method:
'instanciate a new instance of the TCPClient Class
' try to use the connect method to connect to the particular port on the 
particular address
' if the connection worked
' close the connection since we really don't need to do anything more
' mark the status as connected
' if an exception occured then  the port os not open
' clear the error for general principals
' mark it as not open
Dim 
TCP As TcpClient = 
New TcpClient() 
Try
TCP.Connect(IPAddress, 
p.Portid) 
If 
TCP.Connected Then 
    TCP.Close() 
    ClassStatus = 
ClassStatusEnum.DoneConnected 
End
If
Catch 
ex As Exception 
      Err.Clear() 
      ClassStatus = ClassStatusEnum.DoneNotConnected 
End
Try
Of course we now need to write code that checks each port one at a time to see 
if the call (to the previous code) suceeded in connecting. Pretty straight 
forward, so I won't go deeply into the details except that you need to pass it 
two lists of PortStruct (Int32 PortNumber, and String PortUsage ). The first 
list is a list of ports to check passed by value. The second is a list to be 
filled in of ports that are open and is therefore passed by referance (pointer). 
Check each port in sequence and if it connected add it to the list of open ports 
and voila (as they say somewhere).
   
Private Function 
SlowCheckThem(ByVal PortsToTest
As List(Of 
PortStruct), ByVal openPorts
As List(Of 
PortStruct)) As 
Boolean
        Dim rv
As Boolean =
False
        Dim c()
As clsCheckPort = 
Nothing ' create an array of clsCheckPort
        Dim prt
As PortStruct
        Dim j As
Integer = 0
        Dim ThreadArray()
As Thread ' Create 
an array of Threads
       
Try
           
For Each p
As PortStruct In 
PortsToTest ' check each port
                ReDim
Preserve c(j) ' 
instanciate a clsCheckPort for each port to check
                ReDim
Preserve ThreadArray(j)
' instanciate a threasd for each port to check
                c(j) = New 
clsCheckPort(PingAddress, p.PortId)
                c(j).CheckPort() ' start the thread 
. . . passing the port structure to the thread
                j += 1
                Application.DoEvents()
            Next
            For i
As Integer = 
0 To j - 1 ' check 
each instance of the class
                If c(i).CheckStatus = 
clsCheckPort.ClassStatusEnum.DoneConnected Then
'if the status nis done and connected
                    prt.PortId = c(i).Port ' 
create and fill in a structure
                    prt.PortUse = c(i).PortUse
                    openPorts.Add(prt) ' to add it 
to the openPorts list
                End
If
                Application.DoEvents()
            Next
            rv = True
        Catch ex
As Exception
       
End Try
        Return rv
    End Function
If you want to check a lot of ports (for instance 
. . . all of them), you won't use the previous method. You will want to create a 
bunch (an array) of threads that will each check one port. Give it a small 
amount of time to finish checking and then check the results.
   
Private Function 
CheckThem(ByVal PortsToTest
As List(Of 
PortStruct), ByVal openPorts
As List(Of 
PortStruct)) As 
Boolean
        Dim rv
As Boolean =
False
        Dim c()
As clsCheckPort = 
Nothing ' create an array of clsCheckPort
        Dim prt
As PortStruct
        Dim j As
Integer = 0
        Dim ThreadArray()
As Thread ' Create 
an array of Threads
       
Try
           
For Each p
As PortStruct In 
PortsToTest ' check each port
                ReDim
Preserve c(j)
                ReDim
Preserve ThreadArray(j)
                c(j) = New 
clsCheckPort(PingAddress, p.PortId) ' instanciate a 
clsCheckPort for each port to check
                ThreadArray(j) = New 
Thread(AddressOf c(j).CheckPort)
' instanciate a threasd for each port to check
                ThreadArray(j).Start() ' 
start the thread 
                j += 1
                Application.DoEvents()
            Next
            Wait(1000) ' give the last thread 
a moment ot complete
            For i
As Integer = 
0 To j - 1 ' check 
each instance of the class
                If c(i).CheckStatus = 
clsCheckPort.ClassStatusEnum.DoneConnected Then
'if the status nis done and connected
                    prt.PortId = c(i).Port ' 
create and fill in a structure
                    prt.PortUse = c(i).PortUse
                    openPorts.Add(prt) ' to add it 
to the openPorts list
                End
If
                Application.DoEvents()
            Next
            rv = True
        Catch ex
As Exception
       
End Try
        Return rv
    End Function
To check many ports efficiently and quickly we 
pass a different function the same lists as before. In the function we first 
create an array of the class that does the work and then we create an array of 
threads to do the work. Loop through and start all the threads. While you are 
busy starting one thread, the previous thread will have been working its magic. 
If it connects, it will probably be done before you call the next thread. if not 
. . . who cares?
When you finish calling the last thread, just wait for a moment (a few 
milliseconds) to let the last few threads connect if they can. Then start 
checking the class array to see who has connected. Fill the open list in and 
voila (as they say somewhere else). The rest is just normal code.