-
Aug 5th, 2013, 10:34 AM
#1
Thread Starter
Frenzied Member
need help on multi thread pinger
I dont know what to term it so I just titled it multi thread.
Actually I have made this list of site or ip address on a listbox and I was able to ping them one by one through a loop. But this is not what I want to achieve. I dont want a looping style but instead I want to ping all of those in the list with is own thread or instance. I dont really know what proper term. How should I do that?
-
Aug 5th, 2013, 10:53 AM
#2
Re: need help on multi thread pinger
Have you did a search for multi threading examples in VB6?
-
Aug 5th, 2013, 11:09 AM
#3
Thread Starter
Frenzied Member
Re: need help on multi thread pinger
-
Aug 5th, 2013, 11:32 AM
#4
Re: need help on multi thread pinger
Originally Posted by codesearcher
not yet. will check.
Let me save you the trouble.....Don't bother. A lifetime ago I wanted multi-threading to write a network application in VB6. The most promising lead I found was discouraged, even by the guy who wrote it. He only created it as an academic exercise or for his amusement or something but made it very clear that it shouldn't be used in a production application. VB6 programs are COM clients and COM uses a kind of weird threading model that isn't conducive simple multi-threading.
If you want proper threading. You have two choices. Write it in C++ or in a .Net language like VB.Net or C#.
-
Aug 5th, 2013, 11:41 AM
#5
Thread Starter
Frenzied Member
Re: need help on multi thread pinger
ow. so it cant be made under vb6.
-
Aug 5th, 2013, 11:41 AM
#6
Re: need help on multi thread pinger
Ah here I found the article. Can't believe its still here after all this time. Here. Its quite long as he goes into great detail about threading in the COM world. He shows how to use CreateThread to achieve multi-threading but note that towards the end he explicitly states that you shouldn't be using CreateThread in VB6.
-
Aug 5th, 2013, 11:42 AM
#7
Re: need help on multi thread pinger
Originally Posted by codesearcher
ow. so it cant be made under vb6.
Yes it can be done....just not correctly hence it shouldn't be done.
-
Aug 5th, 2013, 11:51 AM
#8
Re: need help on multi thread pinger
If the app is simple enough you could just write it in VB.Net and save yourself from all that CreateThread mess. VS2010 Express is free and this is all it would take to spin up a loop on a worker thread:-
vbnet Code:
' System.Threading.ThreadPool.QueueUserWorkItem(Sub() For I = 1 To 100 Next End Sub)
Now it gets a little more complicated if you want to interact with controls and such but still far less painless than trying to force VB6 to do it.
-
Aug 5th, 2013, 12:02 PM
#9
Re: need help on multi thread pinger
Originally Posted by Niya
Let me save you the trouble.....Don't bother. A lifetime ago I wanted multi-threading to write a network application in VB6. The most promising lead I found was discouraged, even by the guy who wrote it. He only created it as an academic exercise or for his amusement or something but made it very clear that it shouldn't be used in a production application. VB6 programs are COM clients and COM uses a kind of weird threading model that isn't conducive simple multi-threading.
If you want proper threading. You have two choices. Write it in C++ or in a .Net language like VB.Net or C#.
Sure - the threading-models are different - but after all, what's running in the end (InProcess) are just normally (per CreateThread-API) created threads in all cases -
no matter what language or platform - CreateThread creates a Thread in a given Process - what differs is the "isolation of memory-allocations per ThreadLocal-Storage in a COM-STA.
If one wants proper threading in VB6, he can use either the official way (ActiveX-exes) - or helper-libs who are able to work with STA-threads properly
(as e.g. those which come with the RichClient5-Framework).
@the OP
In your case you don't need any threading at all, since the system supports fast pings in a nicely working async fashion per ICMPSendEcho2...
Here's some code, to put into a Form - adjust the BaseIP in the Form_Click-event and click the Form:
Code:
Option Explicit
Private Type ICMP_OPTIONS
ttl As Byte
Tos As Byte
Flags As Byte
OptionsSize As Byte
pOptionsData As Long
End Type
Private Type ICMP_ECHO_REPLY
AddrBytes(0 To 3) As Byte
Status As Long
RoundTripTime As Long
datasize As Long
pData As Long
options As ICMP_OPTIONS
Data(0 To 255) As Byte
End Type
Private Declare Function inet_addr& Lib "Ws2_32" (ByVal S As String)
Private Declare Function IcmpCreateFile Lib "iphlpapi" () As Long
Private Declare Function IcmpCloseHandle Lib "iphlpapi" (ByVal IcmpHandle As Long) As Long
Private Declare Function ICMPSendEcho2 Lib "iphlpapi" Alias "IcmpSendEcho2" (ByVal IcmpHandle As Long, ByVal hEvent As Long, ByVal ApcRoutine As Any, ByVal ApcContext As Long, ByVal DestinationAddress As Long, ByVal RequestData As String, ByVal RequestSize As Long, ByVal RequestOptions As Long, ReplyBuffer As ICMP_ECHO_REPLY, ByVal ReplySize As Long, ByVal TimeOut As Long) As Long
Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Private Declare Function CreateEvent Lib "kernel32" Alias "CreateEventA" (ByVal lpEventAttributes As Long, ByVal bManualReset As Long, ByVal bInitialState As Long, ByVal lpName As String) As Long
Private Declare Function CloseHandle Lib "kernel32" (ByVal hObject As Long) As Long
Private Sub Form_Click()
Dim AnswIP, AnsweringIPs As Collection
Debug.Print "got ping-answers from:"; ScanSubNet(AnsweringIPs, "192.168.0.0"); "machines"
For Each AnswIP In AnsweringIPs
Debug.Print AnswIP
Next
End Sub
Public Function ScanSubNet(AnsweringIPs As Collection, ByVal BaseIP As String) As Long 'a fast "ping-broadcast" over the entire SubNet
Const PingTOutMSec As Long = 100, sPngDat As String = "Ping"
Dim i As Long, hIcmp As Long, Events(1 To 255) As Long, Bufs(1 To 255) As ICMP_ECHO_REPLY
If BaseIP = "127.0.0.1" Then Exit Function
BaseIP = Left$(BaseIP, InStrRev(BaseIP, "."))
hIcmp = IcmpCreateFile: If hIcmp = 0 Then Exit Function
For i = 1 To 255
Events(i) = CreateEvent(0, 0, 0, vbNullString)
If Events(i) Then
ICMPSendEcho2 hIcmp, Events(i), 0&, 0, inet_addr(BaseIP & i), sPngDat, Len(sPngDat), 0, Bufs(i), Len(Bufs(i)), PingTOutMSec
End If
Next i
Sleep PingTOutMSec + 30
Set AnsweringIPs = New Collection
For i = 1 To 255
If Events(i) Then
CloseHandle Events(i)
If Bufs(i).Status = 0 And Bufs(i).AddrBytes(3) <> 0 Then
AnsweringIPs.Add BaseIP & i, BaseIP & i
ScanSubNet = ScanSubNet + 1
End If
End If
Next i
IcmpCloseHandle hIcmp
End Function
Olaf
-
Aug 5th, 2013, 12:15 PM
#10
Re: need help on multi thread pinger
Asynchronous pinging is a good idea too. However, your code isn't using any callbacks. How is it asynchronous ?
-
Aug 5th, 2013, 12:28 PM
#11
Re: need help on multi thread pinger
Originally Posted by Niya
Asynchronous pinging is a good idea too. However, your code isn't using any callbacks. How is it asynchronous ?
The term "Asynchronous" has in my book nothing to do with callbacks (or lambdas <g>)...
I like to think about this stuff as in: "this call will block" - "and this call will not"-terms.
So it's the triggering which is important - not the callback.
And in the above example the (asynchronous, non-blocking) triggering happens in:
ICMPSendEcho2 hIcmp, Events(i), 0&, 0, inet_addr(BaseIP & i), sPngDat, Len(sPngDat), 0, Bufs(i), Len(Bufs(i)), PingTOutMSec
then what follows is a "hardwired, and blocking await" in the mainthread (note the slightly larger timeout-value, compared with the last Max-TOut-param in the call above).
Sleep PingTOutMSec + 30
So after we "awake from our short-Sleep", all the asynchronously (with a max-timeout which was shorter than our sleep-interval) triggered Pings were returning already in one way or another -
what then remains is only the "gathering of the results".
Olaf
-
Aug 5th, 2013, 12:45 PM
#12
Re: need help on multi thread pinger
Originally Posted by Schmidt
then what follows is a "hardwired, and blocking await" in the mainthread (note the slightly larger timeout-value, compared with the last Max-TOut-param in the call above).
This is what I'm talking about. It is blocking. Form_Click doesn't return until all the pings are finished. A proper asynchronous call would have ScanSubNet return immediately and for every ping that is finished, a callback should be invoked to pass the result into the application. I'm not familiar with the ICPM APIs, is there no way to have it invoke a callback ? Do those events have any such functionality ?
The point of using asynchronous code here is to have the UI free and responsive. So you cannot block or poll or anything like that.
-
Aug 5th, 2013, 01:24 PM
#13
Re: need help on multi thread pinger
Originally Posted by Niya
This is what I'm talking about. It is blocking.
Only because I wrote it this way - and also want and prefer it this way.
Originally Posted by Niya
Form_Click doesn't return until all the pings are finished.
As said, because I wrote it this way and because this is exactly how I want to use this ScanSubNet-function.
Originally Posted by Niya
A proper asynchronous call would have ScanSubNet return immediately and for every ping that is finished, a callback should be invoked to pass the result into the application.
Why are you so adamant about those callbacks - in this case (and also when I would use it in a completely async fashion -
e.g. by simply just not calling the Sleep-API - and using a System-Timer-Interval instead) - I don't have to use callbacks to
get my list of answering IPs.
Originally Posted by Niya
I'm not familiar with the ICPM APIs, is there no way to have it invoke a callback ? Do those events have any such functionality ?
Sure, you can use this API also in callback-mode - please read the MSDN.
Originally Posted by Niya
The point of using asynchronous code here is to have the UI free and responsive. So you cannot block or poll or anything like that.
Niya - the UI is free and responsive - since the complete scan of an entire SubNet (254 IPs) is done in only 130msec!
This time-interval is only a few percent above a humans "this was a noticable short delay" detection-capability
(which is at about one tenth of a second).
As said - if I want it without the short sleep-interval - in a non-synchronously callable function which will then not
give back a Collection directly into the calling-code "in-normal-calling-sequence" ... when I just want to fill a list in my Gui ... then I start a
oneshot-timer with a 130msec interval instead of the Sleep-API and do the rest of the processing in the timer-event and fill my GUI-list there.
Believe me, if this would not be a true async demonstration - how do you think those 254 IPs were tested for a result in only 130msec?
You will have to wait quite a bit on each IP, to be sure a potential ping-response was really coming in - so with this necessary waiting on each IP,
it is just not possible to complete the whole task in a sequential fashion for a whole subnet - so those IPs were definitely handled in parallel.
Olaf
-
Aug 5th, 2013, 01:41 PM
#14
Re: need help on multi thread pinger
Originally Posted by Schmidt
Believe me, if this would not be a true async demonstration - how do you think those 254 IPs were tested for a result in only 130msec?
You will have to wait quite a bit on each IP, to be sure a potential ping-response was really coming in - so with this necessary waiting on each IP,
it is just not possible to complete the whole task in a sequential fashion for a whole subnet - so those IPs were definitely handled in parallel.
Fair enough then
-
Aug 6th, 2013, 01:08 AM
#15
Re: need help on multi thread pinger
Here's some multithreading implementation from the CodeBank just in case someone wants to use it.
-
Aug 6th, 2013, 06:20 AM
#16
Re: need help on multi thread pinger
Originally Posted by dee-u
Here's some multithreading implementation from the CodeBank just in case someone wants to use it.
Hilarious that it was named "New" even though it's 7 years old now. Worse yet, all it's merely a convoluted implementation of the very same thing done in the classic Coffee Monitor project spelled out in detail in the VB6 docs and included in the samples on the CDs.
But as already shown above, no multithreading is required to do what was requested.
-
Jan 30th, 2017, 09:42 AM
#17
Re: need help on multi thread pinger
Last edited by DEXWERX; Jan 30th, 2017 at 09:47 AM.
Reason: instant karma
-
Sep 2nd, 2021, 04:30 AM
#18
Re: need help on multi thread pinger
Perhaps like the WINSOCK control array, it is essentially a multi-threaded method. The main bottleneck is whether the network speed is fast enough. After receiving the data, if you want to perform JSON analysis or HTM extraction, this part will be faster if you use multi-threading.
Multiple winhttprequest object events are downloaded, and some may create new threads to collect.
-
Sep 2nd, 2021, 09:19 AM
#19
Re: need help on multi thread pinger
Originally Posted by codesearcher
I dont know what to term it so I just titled it multi thread.
Actually I have made this list of site or ip address on a listbox and I was able to ping them one by one through a loop. But this is not what I want to achieve. I dont want a looping style but instead I want to ping all of those in the list with is own thread or instance. I dont really know what proper term. How should I do that?
Have a look at:
https://www.vbforums.com/showthread....-the-ARP-table
It uses an "arp" call, but all UDP calls exhibit the same problem; they have to wait for a timeout because it is a one way packet (no connection). I addressed the issue by using a separate program, which inherently used a separate thread for each one. For the "arp" call, that timeout was 3.2 seconds, as it actually tried each one 3 times. I would assume that the ping is somewhat similar.
J.A. Coutts
-
Sep 2nd, 2021, 05:44 PM
#20
Re: need help on multi thread pinger
You guys realize that this thread is 8 years old right?
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|