以下介绍C# ping命令的两种实现方法。

创新互联主要从事网站制作、网站设计、网页设计、企业做网站、公司建网站等业务。立足成都服务内丘,10多年网站建设经验,价格优惠、服务专业,欢迎来电咨询建站服务:18980820575
C# ping命令实现:利用原始Socket套接字,实现ICMP协议。
- 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 "没有发现主机";
 - }
 - // 把 Server IP_EndPoint转换成EndPoint
 - IPEndPoint ipepServer = new IPEndPoint(ServerHE.AddressList[0], 0);
 - EndPoint epServer = (ipepServer);
 - // 设定客户机的接收Endpoint
 - fromHE = Dns.GetHostByName(Dns.GetHostName());
 - IPEndPoint ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0], 0);
 - EndPoint EndPointFrom = (ipEndPointFrom);
 - int PacketSize = 0;
 - IcmpPacket packet = new IcmpPacket();
 - // 构建要发送的包
 - 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 "主机没有响应";
 - }
 - 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);
 - }
 - }
 - /// 类结束
 - /// < 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命令执行:执行ping命令
首先,我们用使用Process类,来创建独立的进程,导入System.Diagnostics,
using System.Diagnostics;
实例一个Process类,启动一个独立进程
Process p = new Process();
Process类有一个StartInfo属性,这个是ProcessStartInfo类,包括了一些属性和方法,
下面我们用到了他的几个属性:
设定程序名
p.StartInfo.FileName = "cmd.exe";
关闭Shell的使用
p.StartInfo.UseShellExecute = false;
重定向标准输入
p.StartInfo.RedirectStandardInput = true;
重定向标准输出
p.StartInfo.RedirectStandardOutput = true;
重定向错误输出
p.StartInfo.RedirectStandardError = true;
设置不显示窗口
p.StartInfo.CreateNoWindow = true;
上面几个属性的设置是比较关键的一步。
既然都设置好了那就启动进程吧,
p.Start();
输入要执行的命令,这里就是ping了,
p.StandardInput.WriteLine("ping -n 1 www.iwebtrados.com.cn");
p.StandardInput.WriteLine("exit");
从输出流获取命令执行结果,
string strRst = p.StandardOutput.ReadToEnd();
C# ping命令实现:利用c#2.0新增的Ping类
这里我写的是一个窗体程序。首先添加textbox,listbox,button控件,其中textbox录入域名或IP,listbox显示结果.
在button1_click事件键入
- private void button1_Click(object sender, EventArgs e)
 - {
 - Ping p1 = new Ping(); //只是演示,没有做错误处理
 - PingReply reply = p1.Send(this.textBox1.Text);//阻塞方式
 - displayReply(reply); //显示结果
 - }
 - private void displayReply(PingReply reply) //显示结果
 - {
 - StringBuilder sbuilder ;
 - if (reply.Status == IPStatus.Success)
 - {
 - sbuilder = new StringBuilder();
 - sbuilder.Append(string.Format("Address: {0} ", reply.Address.ToString ()));
 - sbuilder.Append(string.Format("RoundTrip time: {0} ", reply.RoundtripTime));
 - sbuilder.Append(string.Format("Time to live: {0} ", reply.Options.Ttl));
 - sbuilder.Append(string.Format("Don't fragment: {0} ", reply.Options.DontFragment));
 - sbuilder.Append(string.Format("Buffer size: {0} ", reply.Buffer.Length));
 - listBox1.Items.Add(sbuilder.ToString());
 - }
 - }
 
也可以做异步的处理,修改button1_click,并添加PingCompletedCallBack方法
- private void button1_Click(object sender, EventArgs e)
 - {
 - Ping p1 = new Ping();
 - p1.PingCompleted += new PingCompletedEventHandler(this.PingCompletedCallBack);//设置PingCompleted事件处理程序
 - p1.SendAsync(this.textBox1.Text, null);
 - }
 - private void PingCompletedCallBack(object sender, PingCompletedEventArgs e)
 - {
 - if (e.Cancelled)
 - {
 - listBox1.Items.Add("Ping Canncel");
 - return;
 - }
 - if (e.Error != null)
 - {
 - listBox1.Items.Add(e.Error.Message);
 - return;
 - }
 - StringBuilder sbuilder;
 - PingReply reply = e.Reply;
 - if (reply.Status == IPStatus.Success)
 - {
 - sbuilder = new StringBuilder();
 - sbuilder.Append(string.Format("Address: {0} ", reply.Address.ToString()));
 - sbuilder.Append(string.Format("RoundTrip time: {0} ", reply.RoundtripTime));
 - sbuilder.Append(string.Format("Time to live: {0} ", reply.Options.Ttl));
 - sbuilder.Append(string.Format("Don't fragment: {0} ", reply.Options.DontFragment));
 - sbuilder.Append(string.Format("Buffer size: {0} ", reply.Buffer.Length));
 - listBox1.Items.Add(sbuilder.ToString());
 - }
 - }
 
怎么样,相比1、2方式,3是不是简单的多呀。
本文来自网络小筑的博客:《c#下实现ping操作》。
                名称栏目:C#ping命令的实现方法:Ping类的使用
                
                文章网址:http://www.csdahua.cn/qtweb/news26/117726.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网