ZapMan,
Utiliser l'API ne changera pas le fait qu'un timeout assez long est toujours nécessaire pour tester une connection.
Le truc à faire pour ne pas rester planté devant le PC pendant des heures si on veut tester une classe IP complète, c'est d'utiliser des threads ... il n' y a que ça !
Et alors là c'est tout de suite moins simple, bien sûr.
Entre autres parce que le multi-threading pose des tas de problèmes de fiabilité et de stabilité.
De plus, pour tester une suite d'adresses IP, il est nécessaire de créer une boucle qui fait varier les octets de l'adresse IP dans une incrémentation pas simple. En effet une adresse IP est une chaine de caractères (y compris pour la commande OpenNetworkConnection()), mais elle est constituée de valeurs octets non signés, dans l'ordre des poids croissants de gauche à droite.
Or chacun sait que les octets d'un entier long sont placés de droite à gauche etc ...
Donc faire une incrémentation d'une valeur dans une boucle ne marche pas pour pointer une série d'IPs successives.
Alors c'est le binz !
Bon mais, une fois résolus tous ces petits problèmes, on peut arriver à des résultats intéressants quand même.
Le code qui vient n'est pas commenté, mais bon !
Il reste quelques bugs dans la transmission des résultats au ListIcon, à cause du multi-threading que je ne maîtrise pas assez bien pour empêcher l'apparition intempestive de morceaux de chaines de caractères de temps en temps.
...
J'espère néanmoins que cela te donnera plein d'indications sur la méthode et les outils.
Je commenterai mieux ce code dans une prochaine version.
Code : Tout sélectionner
Enumeration
#Window_Main
#StatusBar
#Gadget_Text_Start
#Gadget_Text_End
#Gadget_Button_OK
#Gadget_Button_Cancel
#Gadget_IP_Start
#Gadget_IP_End
#Gadget_ListIcon
EndEnumeration
#MaxThreads = 1000
NewList Threads.l()
Global StartAddress.l, EndAddress.l, sStartAddress.s, sEndAddress.s
Global Run.l
Global TotalConnections.l, TotalThreads.l, CurrentConnection.s
Global OldTotalConnections.l, OldTotalThreads.l, OldCurrentConnection.s
Global hListIconGadget.l
Procedure UpdateListIcon(String.s)
EndProcedure
Procedure TestConnectionToIP(IPAddress.l)
sIPAddress.s = IPString(IPAddress)
#PING_TIMEOUT = 1000
strMessage.s
Echo.ICMP_ECHO_REPLY
EchoMessage.s = "Hello there " + Space(20)
tz = GetTickCount_()
hFile = IcmpCreateFile_()
lngResult = IcmpSendEcho_(hFile, IPAddress, EchoMessage, Len(EchoMessage), 0, Echo, SizeOf(ICMP_ECHO_REPLY), #PING_TIMEOUT)
If lngResult = 0
PingResult = Echo\Status * -1
Else
PingResult = Echo\RoundTripTime
EndIf
lngResult = IcmpCloseHandle_(hFile)
If PingResult >= 0
While WindowEvent() : Wend
CurrentConnection = "Scanning " + sIPAddress + " OK"
If CountList(Threads()) > #MaxThreads
While CountList(Threads()) > #MaxThreads / 2
ResetList(Threads())
NextElement(Threads())
WaitThread(Threads())
Sleep_(2500)
DeleteElement(Threads())
TotalThreads - 1
Wend
EndIf
AddGadgetItem(#Gadget_ListIcon, -1, sIPAddress + Chr(10) + Str(GetTickCount_() - tz))
While WindowEvent() : Wend
EndIf
TotalConnections - 1
TotalThreads - 1
EndProcedure
Procedure RunScan()
Sleep_(500)
StartAddress.l = GetGadgetState(#Gadget_IP_Start)
EndAddress.l = GetGadgetState(#Gadget_IP_End)
iStartAddress = IPAddressField(StartAddress, 0) << 24 + IPAddressField(StartAddress, 1) << 16 + IPAddressField(StartAddress, 2) << 8 + IPAddressField(StartAddress, 3)
iEndAddress = IPAddressField(EndAddress, 0) << 24 + IPAddressField(EndAddress, 1) << 16 + IPAddressField(EndAddress, 2) << 8 + IPAddressField(EndAddress, 3)
For iIPAddress = iStartAddress To iEndAddress
IPAddress = MakeIPAddress(IPAddressField(iIPAddress, 3), IPAddressField(iIPAddress, 2), IPAddressField(iIPAddress, 1), IPAddressField(iIPAddress, 0))
sIPAddress.s = IPString(IPAddress)
CurrentConnection = "Scanning " + sIPAddress
ParameterString.s = Str(IPAddress)
TotalConnections + 1
ThreadID = CreateThread(@TestConnectionToIP(), IPAddress)
TotalThreads + 1
Delay(50)
Next
Run = #FALSE
TotalThreads - 1
EndProcedure
Procedure Stop(ThreadID)
Run = #FALSE
CurrentConnection = "Canceling ..."
If ThreadID <> 0
CurrentConnection = "Canceling " + Str(ThreadID)
KillThread(ThreadID)
TotalThreads - 1
EndIf
ResetList(Threads())
While NextElement(Threads())
CurrentConnection = "Canceling " + Str(Threads())
KillThread(Threads())
TotalThreads - 1
Wend
ClearList(Threads())
CurrentConnection = "Done"
EndProcedure
Procedure DoWeRun(ThreadID.l)
If ThreadID <> 0
Stop(ThreadID)
SendMessage_(hListIconGadget, #LVM_DELETEALLITEMS, 0, 0)
EndIf
Run = #TRUE
CurrentConnection = "Scanning ..."
ThreadID = CreateThread(@RunScan(), 0)
TotalThreads + 1
ProcedureReturn ThreadID
EndProcedure
;
;
;
sStartAddress.s = "194.79.120.0"
sEndAddress.s = "194.79.120.255"
StartAddress.l
EndAddress.l
Quit = #FALSE
Run = #FALSE
WindowXSize = 640
WindowYSize = 480
If InitNetwork()
If OpenWindow(#Window_Main, 0, 0, WindowXSize, WindowYSize, #PB_Window_SystemMenu | #PB_Window_ScreenCentered, "Ip sniffer")
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Escape, #PB_Shortcut_Escape)
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Return, #PB_Shortcut_Return)
AddKeyboardShortcut(#Window_Main, #PB_Shortcut_Delete, #PB_Shortcut_Delete)
If CreateStatusBar(#StatusBar, WindowID())
AddStatusBarField(400)
AddStatusBarField(120)
AddStatusBarField(120)
EndIf
If CreateGadgetList(WindowID(0))
TextGadget(#Gadget_Text_Start, 10, 10, 80, 20, "Start address")
TextGadget(#Gadget_Text_End, 10, 30, 80, 20, "End address")
ButtonGadget(#Gadget_Button_OK, 230, 10, 60, 20, "Go")
ButtonGadget(#Gadget_Button_Cancel, 230, 30, 60, 20, "Cancel")
IPAddressGadget(#Gadget_IP_Start, 100, 10, 120, 20)
IPAddressGadget(#Gadget_IP_End, 100, 30, 120, 20)
hListIconGadget = ListIconGadget(#Gadget_ListIcon, 10, 50, WindowXSize - 20, WindowYSize - 80, "Server found", 120)
AddGadgetColumn(#Gadget_ListIcon, 1, "Time", 80)
EndIf
SetGadgetState(#Gadget_IP_Start, MakeIPAddress(Val(StringField(sStartAddress, 1, ".")), Val(StringField(sStartAddress, 2, ".")), Val(StringField(sStartAddress, 3, ".")), Val(StringField(sStartAddress, 4, "."))))
SetGadgetState(#Gadget_IP_End, MakeIPAddress(Val(StringField(sEndAddress, 1, ".")), Val(StringField(sEndAddress, 2, ".")), Val(StringField(sEndAddress, 3, ".")), Val(StringField(sEndAddress, 4, "."))))
StartAddress = GetGadgetState(#Gadget_IP_Start)
EndAddress = GetGadgetState(#Gadget_IP_End)
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
Quit = #TRUE
Case #PB_Event_Menu
Select EventMenuID()
Case #PB_Shortcut_Escape
If Run
Stop(ThreadID)
Else
Quit = #TRUE
EndIf
Case #PB_Shortcut_Return
ThreadID = DoWeRun(ThreadID)
Case #PB_Shortcut_Delete
Stop(ThreadID)
EndSelect
Case #PB_Event_Gadget
Select EventGadgetID()
Case #Gadget_IP_Start
sStartAddress = GetGadgetText(#Gadget_IP_Start)
StartAddress = GetGadgetState(#Gadget_IP_Start)
Case #Gadget_IP_End
sEndAddress = GetGadgetText(#Gadget_IP_End)
EndAddress = GetGadgetState(#Gadget_IP_End)
Case #Gadget_Button_OK
ThreadID = DoWeRun(ThreadID)
Case #Gadget_Button_Cancel
Stop(ThreadID)
EndSelect
EndSelect
If OldCurrentConnection <> CurrentConnection
OldCurrentConnection = CurrentConnection
StatusBarText(#StatusBar, 0, CurrentConnection)
EndIf
If OldTotalConnections <> TotalConnections
OldTotalConnections = TotalConnections
StatusBarText(#StatusBar, 1, Str(TotalConnections))
EndIf
If OldTotalThreads <> TotalThreads
OldTotalThreads = TotalThreads
StatusBarText(#StatusBar, 2, Str(TotalThreads))
EndIf
Sleep_(1)
Until Quit
Stop(ThreadID)
EndIf
EndIf
TerminateProcess_(GetCurrentProcess_(), 0)
End