Salut,
Je peux t'assurer que ca marche (en tout cas, sous XP). Je l'ai essayé sur plusieurs PC.
Il n'est pas super synchro seulement, il faut attendre, à tout casser, 3 secondes avant que les changement s'effectue.
Version imprimable
Salut,
Je peux t'assurer que ca marche (en tout cas, sous XP). Je l'ai essayé sur plusieurs PC.
Il n'est pas super synchro seulement, il faut attendre, à tout casser, 3 secondes avant que les changement s'effectue.
Désoler... j'ai oublier mon support de stockage hier soir... du coup j'ai pas ramener de source... Par contre Sub0 dit que sont fichier exe qui test les URL gèle sont apllication... du coup je sais pas trop, puisque je me sert surtout des pipes comme espion des consoles :D...
En plus j'ai fait une petite routine a la noix qui permet de récuperer dans un string le résultat de la sortie ecran sans avoir de fichier de transition (je trouve ça un poils plus propre)... j'essay de pas oublié demaint, si non... je me débrouille pour te faire passé mon unit :(
Si non... au cas ou, l'API qui permet la création d'un pipe nomé est CreateNamedPipe et il faudrait lui passé FILE_FLAG_OVERLAPPED dans en second paramètre (dwOpenMode). La lecture et l'ecriture sur le pipe peut alors être effectuer avec ReadFileEx et WriteFileEx. Pour ce connecte a un pipe nomé c'est ConnectNamedPipe qu'il faut employé. Pour lancer un autre processus, je croit que tu sais déjà ;).
@Sub0: Avait tu employé FILE_FLAG_OVERLAPPED ? parce que si oui... je voit vraiment plus ce que l'on peut faire mise a part avec une commande et un fichier de sortie...
Mon XP a l'air du même avis .. mais pas NT ...Citation:
Envoyé par portu
:bug:
Je pense que le délai du ping peut être dû au gethostbyname. Essaie avec ce code là, c'est une classe que j'avais écrite pour faire un ping, il manque certaines choses, mais c'est suffisant pour faire un ping avec l'adresse IP.
Il faut renseigner la propriété HostName avant de faire le ping.
Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276 {----------------------------------------------------------------------------- Unit Name: PingUnit Author: Chris Purpose: History: -----------------------------------------------------------------------------} // // http://www.sockets.com/ms_icmp.htm // unit PingUnit; interface uses Windows, Winsock, SysUtils; type // Options IP PIpOptions=^TIpOptions; TIPOptions=packed record Ttl: Byte; (* time to live *) Tos: Byte; (* type of service (usually 0) *) Flags: Byte; (* IP header flags (usually 0) *) OptionsSize:Byte; (* size of options data (usually 0, max 40) *) OptionsData:pointer; (* options data buffer *) end; TIcmpEchoReply = packed record Address: TInAddr; (* source address *) Status: ULONG; (* IP status *) RoundTripTime: ULONG; (* rount trip time in milliseconds *) DataSize: Word; (* reply data size *) Reserved: Word; (* who knows *) Data: Pointer; (* reply data buffer *) Options: TIPOptions; (* reply options *) end; TIcmpEchoReplyBuffer = packed record Reply: TIcmpEchoReply; Reserved: array[0..7] of Byte; // Complément pour la réponse end; // // // TPing = class private FHIcmpFile: HWnd; // Handle pour utiliser le SendFile protected FErrorCode: Integer; FTimeOut: DWORD; // Time out en ms WSAData: TWSAData; // Pour l'initialisation de Winsock FIPOptions: TIPOptions; FIPAddr: TInAddr; FReply: TIcmpEchoReplyBuffer; FHostName: String; FIPAddress: String; FRevLookup: Boolean; // Faire un reverse lookup ? public constructor Create; destructor Destroy; override; function Ping: Integer; procedure ConvertAddressToIP(const addr: string); // --------------- ------------------- property ErrorCode: Integer read FErrorCode; property TimeToLive: Byte read FIPOptions.Ttl write FIPOptions.Ttl; property TimeOut: DWORD read FTimeOut write FTimeOut; property RoundTripTime: Cardinal read FReply.Reply.RoundTripTime; property Status: Cardinal read FReply.Reply.Status; property HostName: string read FHostName write ConvertAddressToIP; property IPAddress: string read FIPAddress; // Mettre la liste des IP adresses // Mettre la liste des alias end; // mettre 127.0.0.1 par défaut dans l'adresse IP // propriétés: // TTL // TimeOut // nom du host/addr IP // Addr IP EPingError = class(Exception); // ===================================================================== // IMPLEMENTATION // ===================================================================== implementation const MIN_WINSOCK_VERSION = $0101; // ------------------------------------------------------------------------- // Déclaration des fonctions de ICMP.DLL // ------------------------------------------------------------------------- // //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iphlp/iphlp/icmpcreatefile.asp // //HANDLE IcmpCreateFile(void); // function DllIcmpCreateFile(): HWnd; stdcall; external 'icmp.dll' name 'IcmpCreateFile'; // //BOOL IcmpCloseHandle( // HANDLE IcmpHandle //); // function DllIcmpCloseHandle(IcmpHandle: HWnd): BOOL; stdcall; external 'icmp.dll' name 'IcmpCloseHandle'; // //http://msdn.microsoft.com/library/default.asp?url=/library/en-us/iphlp/iphlp/icmpsendecho.asp // //DWORD IcmpSendEcho( // HANDLE IcmpHandle, // IPAddr DestinationAddress, // LPVOID RequestData, // WORD RequestSize, // PIP_OPTION_INFORMATION RequestOptions, // LPVOID ReplyBuffer, // DWORD ReplySize, // DWORD Timeout //); // function DllIcmpSendEcho(IcmpHandle: HWnd; DestinationAddress: TInAddr; RequestData: Pointer; RequestSize: Word; RequestOptions: PIpOptions; ReplyBuffer: Pointer; ReplySize, Timeout: DWORD): DWORD; stdcall; external 'icmp.dll' name 'IcmpSendEcho'; // // // Constructor TPing.Create(); begin // Initialise Winsock, demande Winsock 1.1 Self.FErrorCode := WSAStartup(MIN_WINSOCK_VERSION, Self.WSAData); if Self.FErrorCode <> 0 then raise EPingError.Create('Winsock Init Error'); if Self.WSAData.wVersion <> MIN_WINSOCK_VERSION then raise EPingError.Create('Winsock 1.1 not available'); Self.FHIcmpFile := DllIcmpCreateFile(); if Self.FHIcmpFile = INVALID_HANDLE_VALUE then raise EPingError.Create('Can''t Init ICMP'); Self.FRevLookup := false; // Initialisation des valeurs par défaut des options Self.FIPOptions.Ttl := 255; Self.FIPOptions.Tos := 0; Self.FIPOptions.Flags := 0; Self.FIPOptions.OptionsSize := 0; Self.FIPOptions.OptionsData := nil; Self.FTimeOut := 2000; // 2 sec par défaut // Mettre 127.0.0.1 dans l'addresse IP Self.HostName := '127.0.0.1'; end; // // // destructor TPing.Destroy(); begin // Libération ICMP if Self.FHIcmpFile <> INVALID_HANDLE_VALUE then DllIcmpCloseHandle(Self.FHIcmpFile); // Libère Winsock WSACleanup; end; // // // function TPing.Ping(): Integer; var dwRet: DWORD; begin ZeroMemory(@Self.FReply, Sizeof(TIcmpEchoReplyBuffer)); // Reqest an ICMP echo dwRet := DllIcmpSendEcho(Self.FHIcmpFile, Self.FIPAddr, nil, 0, @Self.FIPOptions, @Self.FReply, Sizeof(TIcmpEchoReplyBuffer), Self.FTimeOut); // dwRet = 0 => erreur if (dwRet = 0) then Self.FErrorCode := GetLastError; end; // // Convertit le hostname ou addresse IP // Effectue une résolution de nom si nécessaire // procedure TPing.ConvertAddressToIP(const addr: string); var usehost:boolean; // vrai si resolution utilisée Host: PHostEnt; ipstr: PChar; pip: PInAddr; begin usehost:= true; Self.FIPAddr.S_addr := inet_addr(PChar(addr)); if Self.FIPAddr.S_addr = INADDR_NONE then begin // Ce n'est pas une adresse IP => essaie de résolution de nom Host := gethostbyname(PChar(addr)) end else begin // Si Flag NameResolution est à False, on ne fait pas de résolution inverse if Self.FRevLookup then Host := gethostbyaddr(Pointer(@Self.FIPAddr), Sizeof(TInAddr), AF_INET) else usehost := false; end; Self.FErrorCode := WSAGetLastError; if usehost then if Host <> nil then begin // Recopie le hostname SetString(Self.FHostName, host.h_name, StrLen(host.h_name)); // Recopie l'adresse IP pip := PInAddr(Host^.h_addr^); Self.FIPAddr := pip^; end else begin if SElf.FErrorCode <> WSANO_DATA then Raise EPingError.Create('gethost... Error'); end; // Converti l'adresse IP en chaine ipstr := inet_ntoa(Self.FIPAddr); if Assigned(ipstr) then SetString(Self.FIPAddress, ipstr, StrLen(ipstr)) else Raise EPingError.Create('inet_ntoa Error'); end; // --------------------------- Fin de l'unité ----------------------------- end.
Salut,
Si tu veux tu peux essayer ça :
C'est super rapide et tu faire un ping à l'aide de l'adresse IP du poste ou de son nom.Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134 unit uPing; interface uses Windows, SysUtils, Classes; type TSunB = packed record s_b1, s_b2, s_b3, s_b4: byte; end; TSunW = packed record s_w1, s_w2: word; end; PIPAddr = ^TIPAddr; TIPAddr = record case integer of 0: (S_un_b: TSunB); 1: (S_un_w: TSunW); 2: (S_addr: longword); end; IPAddr = TIPAddr; function IcmpCreateFile : THandle; stdcall; external 'icmp.dll'; function IcmpCloseHandle (icmpHandle : THandle) : boolean; stdcall; external 'icmp.dll' function IcmpSendEcho (IcmpHandle : THandle; DestinationAddress : IPAddr; RequestData : Pointer; RequestSize : Smallint; RequestOptions : pointer; ReplyBuffer : Pointer; ReplySize : DWORD; Timeout : DWORD) : DWORD; stdcall; external 'icmp.dll'; function Ping(InetAddress : string) : boolean; implementation uses WinSock; function Fetch(var AInput: string; const ADelim: string = ' '; const ADelete: Boolean = true) : string; var iPos: Integer; begin if ADelim = #0 then begin // AnsiPos does not work with #0 iPos := Pos(ADelim, AInput); end else begin iPos := Pos(ADelim, AInput); end; if iPos = 0 then begin Result := AInput; if ADelete then begin AInput := ''; end; end else begin result := Copy(AInput, 1, iPos - 1); if ADelete then begin Delete(AInput, 1, iPos + Length(ADelim) - 1); end; end; end; procedure TranslateStringToTInAddr(AIP: string; var AInAddr); var phe: PHostEnt; pac: PChar; GInitData: TWSAData; begin WSAStartup($101, GInitData); try phe := GetHostByName(PChar(AIP)); if Assigned(phe) then begin pac := phe^.h_addr_list^; if Assigned(pac) then begin with TIPAddr(AInAddr).S_un_b do begin s_b1 := Byte(pac[0]); s_b2 := Byte(pac[1]); s_b3 := Byte(pac[2]); s_b4 := Byte(pac[3]); end; end else begin raise Exception.Create('Error getting IP from HostName'); end; end else begin raise Exception.Create('Error getting HostName'); end; except FillChar(AInAddr, SizeOf(AInAddr), #0); end; WSACleanup; end; // ** Exécute des ping sur les PC function Ping(InetAddress : string) : boolean; var Handle : THandle; InAddr : IPAddr; DW : DWORD; rep : array[1..128] of byte; begin result := false; Handle := IcmpCreateFile; if Handle = INVALID_HANDLE_VALUE then Exit; TranslateStringToTInAddr(InetAddress, InAddr); DW := IcmpSendEcho(Handle, InAddr, nil, 0, nil, @rep, 128, 0); Result := (DW <> 0); IcmpCloseHandle(Handle); end; end.
Je trouve que c'est super partique.
Bon dev.
Isa
Moi, je ne pense pas que le Ping soit la meilleur solution pour ce problème.
Pcq il faut connaitre l'ip host et ca crée une charge réseau inutile. Bon, il seul pc sur le réseau qui fait cela, ca va. Mais si tu as 100 pc du réseau qui font cela simultanément , catastrophe.
la meilleur est de pouvoir récurer l'adresse ip du pc aussi rapidement que ipconfig le fait :roll: pour bien faire.
Un PC qui n'est pas sur le réseau à une adresse IP donc ipconfig n'est pas une solution.
C'est pour ca que je fais un TNSPING de mon instance Oracle.Citation:
Envoyé par portu
:wink:
En effet, tout dépend maintenant de comment il sont configurés(DHCP ou Static). Je partais du principe du DHCP.Citation:
Envoyé par cpdump
Si l'ordi a une adresse, il est dans le réseau, si il n'est pas dans le réseau, il n'a plus d'adresse (sous DHCP)
DHCP ou STATIC :
Si le câle réseau est débranché ou ne répond plus, il n'y a plus d'adresse IP.
?????Citation:
C'est pour ca que je fais un TNSPING de mon instance Oracle.
>> cpdump
Ca me donne toujours la même chose, même avec le cable débranché.
:(
Selon, le site sur lequel le PC se trouve, je ne vais pas pinguer un serveur se trouvant à l'autre bout du pays, ou à l'étranger !?Citation:
Envoyé par portu
Par contre, je peux connaitre l'instance Oracle.
:wink:
Une adresse IP est associée à une interface (ethernet dans ce cas), que cette interface soit relié à un réseau ou pas !Citation:
Envoyé par portu
Même débranché le PC garde son adresse IP, en DHCP il garde son adresse pendant toute la durée du bail et garde la même s'il n'arrive pas a renouveler l'adresse IP.
Est ce que tu as bien la liste Self.FRevLookup := false; dans le create, j'avais posté une version de debug, mais j'ai édité après.Citation:
Envoyé par Lung
Est ce que tu as essayer de l'executer en pas à pas voir ou ce situe le délai ? On est bien d'accord que tu ping directement avec l'adresse IP et non un nom de machine ?
Sous XP, mais pas sous NT ...Citation:
Envoyé par Isa31
:bug:
8O Drôle tout ca, je suis en DHCP. Mon bail exprire Jeudi et si je me déconnecte du réseau, j'arrive pas à pinger sur mon adresse que mon DHCp ma attribué.Citation:
Envoyé par cpdump
Comment expliques tu cela ?
Non, j'utilisais un nom ... :oops:Citation:
Envoyé par cpdump
Par contre, avec une adresse IP, ca a l'air de réagir très vite, même sur NT !
:yaisse:
Je creuse ...
:wink:
Quand le bail expire je ne suis pas sûr à 100%, mais si le bail n'a pas exipré, tu peux pinger ton adresse (je ne parle pas d'adresses allouées avec un accès à distance).Citation:
Envoyé par portu
Ben... je copie/colle quand même mon bout de code :(
Avec SPipe une constante initialiser comme tu veux...Code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68 Function RunSpyStdOut(Const Commande:String; Var Out:String): Integer; Label DebtIteration; Var Start : TStartupInfo ; Process : TProcessInformation; Sa : TSecurityAttributes; PipeOut, PipeIn , Readed : Cardinal; Buffer : String ; WhatApen: DWord; begin RunSpyStdOut := -1; // Choix de la taille du Buffer... SetLength(Buffer, SPipe); // Initialisation des attributs de sécurité FillChar (Sa, SizeOf(Sa), #0); Sa.nLength := SizeOf (Sa); Sa.bInheritHandle := TRUE; // Création du Pipe if not CreatePipe(PipeIn, PipeOut, @Sa, SPipe) then Exit; // Paramétrage du lancemant de l'application FillChar(Start,SizeOf(Start),#0); Start.cb := SizeOf(Start); Start.dwFlags := STARTF_USESTDHANDLES Or STARTF_USESHOWWINDOW; Start.hStdOutput := PipeOut; Start.wShowWindow := SW_HIDE; // Création du Processus pour l'application If CreateProcess(Nil, PChar(Commande), Nil, Nil, True, 0, Nil, Nil, Start,Process) Then Begin // OK... // On peut, et on doit, fermer le handle d'écriture du pipe. // 1 - Parceque de toute façon on ne va rien écrire dedans. // 2 - Parceque si non la fontion ReadFile risque de rester bloquer car un // Handle est toujours ouvert à la fermeture de l'application dont on // récupaire la sortie standard. CloseHandle (PipeOut); Repeat // Quoi qu'il se passe, on va lire le flux du pipe car, s'il est plein, // la fonction d'écriture de la console dans le pipe ne rend pas la main // au programme apellant. // Si le pipe est plein, le programme ne reprend jamais la main !!! ReadFile(PipeIn, Buffer[1], SPipe, Readed, nil); Out:=Out+copy(Buffer,1,Readed); // ...on va patienté quelque miliseconde. WhatApen := WaitForSingleObject(Process.hProcess, 125); Application.ProcessMessages; until WhatApen = WAIT_OBJECT_0; End; CloseHandle (PipeIn); GetExitCodeProcess(Process.hProcess, WhatApen); RunSpyStdOut:=WhatApen; End;
Bon l'exemple utilise un Pipe annonyme et ne ce sert pas de l'ecriture sur entrée standar, mais le principe reste identique. Suaf qu'en plus le processus enfant doit ce connecter au Pipe nommé créé par le parent...
Comment ça le code n'a rien a voir :wink:
Forcement, le ping essaie de faire une resolution de nom et attend la réponse avant de faire le ping, vu que le cable est débranché, il faut attendre le timeout (plusieurs secondes). De plus s'il y a plusieurs DNS déclarés, je ne sais plus s'il lance un requête sur tous les DNS en même temps ou s'il les fait un par un.Citation:
Envoyé par Lung
PS: /dev/null passer par une commande "dos" ne change rien au problème, et c'est franchement à éviter si on peut passer par les API pour le ping.
@cpdump: Je sais bien... t'en fais pas j'essay pas d'envoyer ailleur la balle ;) C'est juste que j'avais prévue de poster ce morceau de code donc je l'ai fait :p. De plus... relit le post... tu verras sur quoi on été partie à l'origine et comment on a bifurqué :?