C# ping命令的實現(xiàn)方法:Ping類的使用
以下介紹C# ping命令的兩種實現(xiàn)方法。
C# ping命令實現(xiàn):利用原始Socket套接字,實現(xiàn)ICMP協(xié)議。
- using System;
 - using System.Collections.Generic;
 - using System.Text;
 - using System.Net;
 - using System.Net.Sockets;
 - namespace PingC
 - {
 - class ping
 - {
 - const int SOCKET_ERROR = -1;
 - const int ICMP_ECHO = 8;
 - static void Main(string[] args)
 - {
 - ping p = new ping();
 - Console.WriteLine("請輸入要 Ping 的IP或者主機名字:");
 - string MyUrl = Console.ReadLine();
 - Console.WriteLine("正在 Ping " + MyUrl + " ……");
 - Console.Write(p.PingHost(MyUrl));
 - }
 - public string PingHost(string host)
 - {
 - // 聲明 IPHostEntry
 - IPHostEntry ServerHE, fromHE;
 - int nBytes = 0;
 - int dwStart = 0, dwStop = 0;
 - //初始化ICMP的Socket
 - Socket socket =
 - new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
 - socket.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.SendTimeout, 1000);
 - // 得到Server EndPoint
 - try
 - {
 - ServerHE = Dns.GetHostByName(host);
 - }
 - catch (Exception)
 - {
 - return "沒有發(fā)現(xiàn)主機";
 - }
 - // 把 Server IP_EndPoint轉(zhuǎn)換成EndPoint
 - IPEndPoint ipepServer = new IPEndPoint(ServerHE.AddressList[0], 0);
 - EndPoint epServer = (ipepServer);
 - // 設(shè)定客戶機的接收Endpoint
 - fromHE = Dns.GetHostByName(Dns.GetHostName());
 - IPEndPoint ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0], 0);
 - EndPoint EndPointFrom = (ipEndPointFrom);
 - int PacketSize = 0;
 - IcmpPacket packet = new IcmpPacket();
 - // 構(gòu)建要發(fā)送的包
 - packet.Type = ICMP_ECHO; //8
 - packet.SubCode = 0;
 - packet.CheckSum =0;
 - packet.Identifier = 45;
 - packet.SequenceNumber = 0;
 - int PingData = 24; // sizeof(IcmpPacket) - 8;
 - packet.Data = new Byte[PingData];
 - // 初始化Packet.Data
 - for (int i = 0; i < PingData; i++)
 - {
 - packet.Data[i] = (byte)'#';
 - }
 - //Variable to hold the total Packet size
 - PacketSize = 32;
 - Byte[] icmp_pkt_buffer = new Byte[PacketSize];
 - Int32 Index = 0;
 - //again check the packet size
 - Index = Serialize(
 - packet,
 - icmp_pkt_buffer,
 - PacketSize,
 - PingData);
 - //if there is a error report it
 - if (Index == -1)
 - {
 - return "Error Creating Packet";
 - }
 - // convert into a UInt16 array
 - //Get the Half size of the Packet
 - Double double_length = Convert.ToDouble(Index);
 - Double dtemp = Math.Ceiling(double_length / 2);
 - int cksum_buffer_length = Index/2;
 - //Create a Byte Array
 - UInt16[] cksum_buffer = new UInt16[cksum_buffer_length];
 - //Code to initialize the Uint16 array
 - int icmp_header_buffer_index = 0;
 - for (int i = 0; i < cksum_buffer_length; i++)
 - {
 - cksum_buffer[i] =
 - BitConverter.ToUInt16(icmp_pkt_buffer, icmp_header_buffer_index);
 - icmp_header_buffer_index += 2;
 - }
 - //Call a method which will return a checksum
 - UInt16 u_cksum = checksum(cksum_buffer, cksum_buffer_length);
 - //Save the checksum to the Packet
 - packet.CheckSum = u_cksum;
 - // Now that we have the checksum, serialize the packet again
 - Byte[] sendbuf = new Byte[PacketSize];
 - //again check the packet size
 - Index = Serialize(
 - packet,
 - sendbuf,
 - PacketSize,
 - PingData);
 - //if there is a error report it
 - if (Index == -1)
 - {
 - return "Error Creating Packet";
 - }
 - dwStart = System.Environment.TickCount; // Start timing
 - //send the Packet over the socket
 - if ((nBytes = socket.SendTo(sendbuf, PacketSize, 0, epServer)) == SOCKET_ERROR)
 - {
 - return "Socket Error: cannot send Packet";
 - }
 - // Initialize the buffers. The receive buffer is the size of the
 - // ICMP header plus the IP header (20 bytes)
 - Byte[] ReceiveBuffer = new Byte[256];
 - nBytes = 0;
 - //Receive the bytes
 - bool recd = false;
 - int timeout = 0;
 - //loop for checking the time of the server responding
 - while (!recd)
 - {
 - nBytes = socket.ReceiveFrom(ReceiveBuffer, 256, 0, ref EndPointFrom);
 - if (nBytes == SOCKET_ERROR)
 - {
 - return "主機沒有響應(yīng)";
 - }
 - else if (nBytes > 0)
 - {
 - dwStop = System.Environment.TickCount - dwStart; // stop timing
 - return "Reply from " + epServer.ToString() + " in "
 - + dwStop + "ms. Received: " + nBytes + " Bytes.";
 - }
 - timeout = System.Environment.TickCount - dwStart;
 - if (timeout > 1000)
 - {
 - return "超時";
 - }
 - }
 - //close the socket
 - socket.Close();
 - return "";
 - }
 - /// < summary>
 - /// This method get the Packet and calculates the total size
 - /// of the Pack by converting it to byte array
 - /// < /summary>
 - public static Int32 Serialize(IcmpPacket packet, Byte[] Buffer,
 - Int32 PacketSize, Int32 PingData)
 - {
 - Int32 cbReturn = 0;
 - // serialize the struct into the array
 - int Index = 0;
 - Byte[] b_type = new Byte[1];
 - b_type[0] = (packet.Type);
 - Byte[] b_code = new Byte[1];
 - b_code[0] = (packet.SubCode);
 - Byte[] b_cksum = BitConverter.GetBytes(packet.CheckSum);
 - Byte[] b_id = BitConverter.GetBytes(packet.Identifier);
 - Byte[] b_seq = BitConverter.GetBytes(packet.SequenceNumber);
 - Array.Copy(b_type, 0, Buffer, Index, b_type.Length);
 - Index += b_type.Length;
 - Array.Copy(b_code, 0, Buffer, Index, b_code.Length);
 - Index += b_code.Length;
 - Array.Copy(b_cksum, 0, Buffer, Index, b_cksum.Length);
 - Index += b_cksum.Length;
 - Array.Copy(b_id, 0, Buffer, Index, b_id.Length);
 - Index += b_id.Length;
 - Array.Copy(b_seq, 0, Buffer, Index, b_seq.Length);
 - Index += b_seq.Length;
 - // copy the data
 - Array.Copy(packet.Data, 0, Buffer, Index, PingData);
 - Index += PingData;
 - if (Index != PacketSize/* sizeof(IcmpPacket) */)
 - {
 - cbReturn = -1;
 - return cbReturn;
 - }
 - cbReturn = Index;
 - return cbReturn;
 - }
 - /// < summary>
 - /// This Method has the algorithm to make a checksum
 - /// < /summary>
 - public static UInt16 checksum(UInt16[] buffer, int size)
 - {
 - Int32 cksum = 0;
 - int counter;
 - counter = 0;
 - while (size > 0)
 - {
 - UInt16 val = buffer[counter];
 - cksum += buffer[counter];
 - counter += 1;
 - size -= 1;
 - }
 - cksum = (cksum >> 16) + (cksum & 0xffff);
 - cksum += (cksum >> 16);
 - return (UInt16)(~cksum);
 - }
 - }
 - /// 類結(jié)束
 - /// < summary>
 - /// Class that holds the Pack information
 - /// < /summary>
 - public class IcmpPacket
 - {
 - public Byte Type; // type of message
 - public Byte SubCode; // type of sub code
 - public UInt16 CheckSum; // ones complement checksum of struct
 - public UInt16 Identifier; // identifier
 - public UInt16 SequenceNumber; // sequence number
 - public Byte[] Data;
 - } // class IcmpPacket
 - }
 
C# ping命令執(zhí)行:執(zhí)行ping命令
首先,我們用使用Process類,來創(chuàng)建獨立的進程,導(dǎo)入System.Diagnostics,
using System.Diagnostics;
實例一個Process類,啟動一個獨立進程
Process p = new Process();
Process類有一個StartInfo屬性,這個是ProcessStartInfo類,包括了一些屬性和方法,
下面我們用到了他的幾個屬性:
設(shè)定程序名
p.StartInfo.FileName = "cmd.exe";
關(guān)閉Shell的使用
p.StartInfo.UseShellExecute = false;
重定向標(biāo)準(zhǔn)輸入
p.StartInfo.RedirectStandardInput = true;
重定向標(biāo)準(zhǔn)輸出
p.StartInfo.RedirectStandardOutput = true;
重定向錯誤輸出
p.StartInfo.RedirectStandardError = true;
設(shè)置不顯示窗口
p.StartInfo.CreateNoWindow = true;
上面幾個屬性的設(shè)置是比較關(guān)鍵的一步。
既然都設(shè)置好了那就啟動進程吧,
p.Start();
輸入要執(zhí)行的命令,這里就是ping了,















 
 
 




 
 
 
 