Asp.net编写的PING工具

导 读:PING 是一个用来检测网络连接速度的使用工具,下面的文章将介绍在C#中利用System.Net.Sockets 来创建一个自己的PING 工具。

--------------------------------------------------------------------------------

PING 是一个用来检测网络连接速度的工具,它会在本机和给出的远程主机名之间建立一个SOCKET 连接并向其发送一个ICMP协议格式的数据包,然后远程主机作出响应,发回一个数据包,通过计算发送到接收数据包的时间间隔,我们可以确定连接的速度。

使用方法 ping

  1<hostname> [/r] 
  2
  3<hostname> 主机名 
  4
  5[/r] 可选属性,决定是否连续的 ping 远程主机。 
  6
  7下面是代码: 
  8
  9///ping.cs 
 10
 11namespace SaurabhPing 
 12
 13{ 
 14
 15using System; 
 16
 17using System.Net; 
 18
 19using System.Net.Sockets; 
 20
 21/// <summary>
 22
 23/// 主要的类:ping 
 24
 25/// </summary>
 26
 27class Ping 
 28
 29{ 
 30
 31//声明几个常量 
 32
 33const int SOCKET_ERROR = -1; 
 34
 35const int ICMP_ECHO = 8; 
 36
 37/// <summary>
 38
 39/// 这里取得Hostname参数 
 40
 41/// </summary>
 42
 43public static void Main(string[] argv) 
 44
 45{ 
 46
 47if(argv.Length==0) 
 48
 49{ 
 50
 51//If user did not enter any Parameter inform him 
 52
 53Console.WriteLine("Usage:Ping <hostname> /r") ; 
 54
 55Console.WriteLine("<hostname> The name of the Host who you want to ping"); 
 56
 57Console.WriteLine("/r Ping the host continuously") ; 
 58
 59} 
 60
 61else if(argv.Length==1) 
 62
 63{ 
 64
 65//Just the hostname provided by the user 
 66
 67//call the method "PingHost" and pass the HostName as a parameter 
 68
 69PingHost(argv[0]) ; 
 70
 71} 
 72
 73else if(argv.Length==2) 
 74
 75{ 
 76
 77//the user provided the hostname and the switch 
 78
 79if(argv[1]=="/r") 
 80
 81{ 
 82
 83//loop the ping program 
 84
 85while(true) 
 86
 87{ 
 88
 89//call the method "PingHost" and pass the HostName as a parameter 
 90
 91PingHost(argv[0]) ; 
 92
 93} 
 94
 95} 
 96
 97else 
 98
 99{ 
100
101//if the user provided some other switch 
102
103PingHost(argv[0]) ; 
104
105} 
106
107} 
108
109else 
110
111{ 
112
113//Some error occurred 
114
115Console.WriteLine("Error in Arguments") ; 
116
117} 
118
119} 
120
121/// <summary>
122
123/// 主要的方法,用来取得IP, 
124
125/// 并计算响应时间 
126
127/// </summary>
128
129public static void PingHost(string host) 
130
131{ 
132
133//Declare the IPHostEntry 
134
135IPHostEntry serverHE, fromHE; 
136
137int nBytes = 0; 
138
139int dwStart = 0, dwStop = 0; 
140
141//Initilize a Socket of the Type ICMP 
142
143Socket socket = 
144
145new Socket(AddressFamily.AfINet, SocketType.SockRaw, ProtocolType.ProtICMP); 
146
147// Get the server endpoint 
148
149try 
150
151{ 
152
153serverHE = DNS.GetHostByName(host); 
154
155} 
156
157catch(Exception) 
158
159{ 
160
161Console.WriteLine("Host not found"); // fail 
162
163return ; 
164
165} 
166
167// Convert the server IP_EndPoint to an EndPoint 
168
169IPEndPoint ipepServer = new IPEndPoint(serverHE.AddressList[0], 0); 
170
171EndPoint epServer = (ipepServer); 
172
173// Set the receiving endpoint to the client machine 
174
175fromHE = DNS.GetHostByName(DNS.GetHostName()); 
176
177IPEndPoint ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0], 0); 
178
179EndPoint EndPointFrom = (ipEndPointFrom); 
180
181int PacketSize = 0; 
182
183IcmpPacket packet = new IcmpPacket(); 
184
185// Construct the packet to send 
186
187packet.Type = ICMP_ECHO; //8 
188
189packet.SubCode = 0; 
190
191packet.CheckSum = UInt16.Parse("0"); 
192
193packet.Identifier = UInt16.Parse("45"); 
194
195packet.SequenceNumber = UInt16.Parse("0"); 
196
197int PingData = 32; // sizeof(IcmpPacket) - 8; 
198
199packet.Data = new Byte[PingData]; 
200
201//Initilize the Packet.Data 
202
203for (int i = 0; i &lt; PingData; i++) 
204
205{ 
206
207packet.Data[i] = (byte)'#'; 
208
209} 
210
211//Variable to hold the total Packet size 
212
213PacketSize = PingData + 8; 
214
215Byte [] icmp_pkt_buffer = new Byte[ PacketSize ]; 
216
217Int32 Index = 0; 
218
219//Call a Method Serialize which counts 
220
221//The total number of Bytes in the Packet 
222
223Index = Serialize( 
224
225packet, 
226
227icmp_pkt_buffer, 
228
229PacketSize, 
230
231PingData ); 
232
233//Error in Packet Size 
234
235if( Index == -1 ) 
236
237{ 
238
239Console.WriteLine("Error in Making Packet"); 
240
241return ; 
242
243} 
244
245// now get this critter into a UInt16 array 
246
247//Get the Half size of the Packet 
248
249Double double_length = Convert.ToDouble(Index); 
250
251Double dtemp = Math.Ceil( double_length / 2); 
252
253int cksum_buffer_length = Convert.ToInt32(dtemp); 
254
255//Create a Byte Array 
256
257UInt16 [] cksum_buffer = new UInt16[cksum_buffer_length]; 
258
259//Code to initialize the Uint16 array 
260
261int icmp_header_buffer_index = 0; 
262
263for( int i = 0; i &lt; cksum_buffer_length; i++ ) { 
264
265cksum_buffer[i] = 
266
267BitConverter.ToUInt16(icmp_pkt_buffer,icmp_header_buffer_index); 
268
269icmp_header_buffer_index += 2; 
270
271} 
272
273//Call a method which will return a checksum 
274
275UInt16 u_cksum = checksum(cksum_buffer, cksum_buffer_length); 
276
277//Save the checksum to the Packet 
278
279packet.CheckSum = u_cksum; 
280
281// Now that we have the checksum, serialize the packet again 
282
283Byte [] sendbuf = new Byte[ PacketSize ]; 
284
285//again check the packet size 
286
287Index = Serialize( 
288
289packet, 
290
291sendbuf, 
292
293PacketSize, 
294
295PingData ); 
296
297//if there is a error report it 
298
299if( Index == -1 ) 
300
301{ 
302
303Console.WriteLine("Error in Making Packet"); 
304
305return ; 
306
307} 
308
309dwStart = System.Environment.TickCount; // Start timing 
310
311//send the Pack over the socket 
312
313if ((nBytes = socket.SendTo(sendbuf, PacketSize, 0, epServer)) == SOCKET_ERROR) 
314
315{ 
316
317Console.WriteLine("Socket Error cannot Send Packet"); 
318
319} 
320
321// Initialize the buffers. The receive buffer is the size of the 
322
323// ICMP header plus the IP header (20 bytes) 
324
325Byte [] ReceiveBuffer = new Byte[256]; 
326
327nBytes = 0; 
328
329//Receive the bytes 
330
331bool recd =false ; 
332
333int timeout=0 ; 
334
335//loop for checking the time of the server responding 
336
337while(!recd) 
338
339{ 
340
341nBytes = socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref EndPointFrom); 
342
343if (nBytes == SOCKET_ERROR) 
344
345{ 
346
347Console.WriteLine("Host not Responding") ; 
348
349recd=true ; 
350
351break; 
352
353} 
354
355else if(nBytes&gt;0) 
356
357{ 
358
359dwStop = System.Environment.TickCount - dwStart; // stop timing 
360
361Console.WriteLine("Reply from "+epServer.ToString()+" in " 
362
363+dwStop+"MS :Bytes Received"+nBytes); 
364
365recd=true; 
366
367break; 
368
369} 
370
371timeout=System.Environment.TickCount - dwStart; 
372
373if(timeout&gt;1000) 
374
375{ 
376
377Console.WriteLine("Time Out") ; 
378
379recd=true; 
380
381} 
382
383} 
384
385//close the socket 
386
387socket.Close(); 
388
389} 
390
391/// <summary>
392
393/// This method get the Packet and calculates the total size 
394
395/// of the Pack by converting it to byte array 
396
397/// </summary>
398
399public static Int32 Serialize(IcmpPacket packet, Byte[] Buffer, 
400
401Int32 PacketSize, Int32 PingData ) 
402
403{ 
404
405Int32 cbReturn = 0; 
406
407// serialize the struct into the array 
408
409int Index=0; 
410
411Byte [] b_type = new Byte[1]; 
412
413b_type[0] = (packet.Type); 
414
415Byte [] b_code = new Byte[1]; 
416
417b_code[0] = (packet.SubCode); 
418
419Byte [] b_cksum = BitConverter.GetBytes(packet.CheckSum); 
420
421Byte [] b_id = BitConverter.GetBytes(packet.Identifier); 
422
423Byte [] b_seq = BitConverter.GetBytes(packet.SequenceNumber); 
424
425// Console.WriteLine("Serialize type "); 
426
427Array.Copy( b_type, 0, Buffer, Index, b_type.Length ); 
428
429Index += b_type.Length; 
430
431// Console.WriteLine("Serialize code "); 
432
433Array.Copy( b_code, 0, Buffer, Index, b_code.Length ); 
434
435Index += b_code.Length; 
436
437// Console.WriteLine("Serialize cksum "); 
438
439Array.Copy( b_cksum, 0, Buffer, Index, b_cksum.Length ); 
440
441Index += b_cksum.Length; 
442
443// Console.WriteLine("Serialize id "); 
444
445Array.Copy( b_id, 0, Buffer, Index, b_id.Length ); 
446
447Index += b_id.Length; 
448
449Array.Copy( b_seq, 0, Buffer, Index, b_seq.Length ); 
450
451Index += b_seq.Length; 
452
453// copy the data 
454
455Array.Copy( packet.Data, 0, Buffer, Index, PingData ); 
456
457Index += PingData; 
458
459if( Index != PacketSize/* sizeof(IcmpPacket) */) { 
460
461cbReturn = -1; 
462
463return cbReturn; 
464
465} 
466
467cbReturn = Index; 
468
469return cbReturn; 
470
471} 
472
473/// <summary>
474
475/// This Method has the algorithm to make a checksum 
476
477/// </summary>
478
479public static UInt16 checksum( UInt16[] buffer, int size ) 
480
481{ 
482
483Int32 cksum = 0; 
484
485int counter; 
486
487counter = 0; 
488
489while ( size &gt; 0 ) { 
490
491UInt16 val = buffer[counter]; 
492
493cksum += Convert.ToInt32( buffer[counter] ); 
494
495counter += 1; 
496
497size -= 1; 
498
499} 
500
501cksum = (cksum &gt;&gt; 16) + (cksum &amp; 0xffff); 
502
503cksum += (cksum &gt;&gt; 16); 
504
505return (UInt16)(~cksum); 
506
507} 
508
509} // class ping 
510
511/// <summary>
512
513/// Class that holds the Pack information 
514
515/// </summary>
516
517public class IcmpPacket 
518
519{ 
520
521public Byte Type; // type of message 
522
523public Byte SubCode; // type of sub code 
524
525public UInt16 CheckSum; // ones complement checksum of struct 
526
527public UInt16 Identifier; // identifier 
528
529public UInt16 SequenceNumber; // sequence number 
530
531public Byte [] Data; 
532
533} // class IcmpPacket 
534
535}</hostname></hostname></hostname></hostname>
Published At
Categories with Web编程
Tagged with
comments powered by Disqus