用户登录  |  用户注册
首 页商业源码原创产品编程论坛
当前位置:PB创新网文章中心编程技巧编程其他

ping程序的C#实现

减小字体 增大字体 作者:佚名  来源:本站整理  发布时间:2009-03-16 19:35:48

cornfield编了一个.Net下的ping控制台程序,从简单的程序结构可见.Net的强大!以下是程序源码,望大家多多跟贴,讨论改进,一起成长!
namespace Cornfield
{
  using System;
  using System.Net;
  using System.Net.Sockets;


  class MyPing
  {


    public static void Main(string[] argv)
    {
          if(argv.Length==1 argv.Length==2)
        PingHost(argv);
         else
          {
        Console.WriteLine("Invalid Command.");
        Console.WriteLine("Usage : 1. MyPing <hostname>.") ;
        Console.WriteLine("       2. MyPing <hostname> <client>.");
          }
     
    }
    
    public static void PingHost(string[] hostclient)
    {
    file://初始化Socket套接字
    file://三个参数分别为:
    //    1。解析地址的地址模式,较常用的为AddressFamily.InterNetwork,即IPv4地址。
    //    2。Socket套接字类型,一般为SocketType.Raw原始类型。
    //    3。网络协议类型,这里Ping用的是Internet控制报文协议ProtocolType.Icmp.   
    Socket socket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
   
    IPHostEntry hostInfo;
    try
    {
      file://解析主机IP入口
      hostInfo = Dns.GetHostByName(hostclient[0]);   
    }
    catch(Exception)
    {
      file://解析主机名错误。
      Console.WriteLine("Unknown host {0}.",hostclient[0]);
      return ;
    }
    // 取主机0号端口
    EndPoint hostPoint= (EndPoint)new IPEndPoint(hostInfo.AddressList[0], 0);   

    IPHostEntry clientInfo;
    try
    {
        if (hostclient.Length==2)
            clientInfo =Dns.GetHostByName(hostclient[1]);
        else
              clientInfo = Dns.GetHostByName(Dns.GetHostName());
    }
    catch(Exception)
    {
      file://解析主机名错误。
      Console.WriteLine("Unknown client {1}.",hostclient[1]);
      return ;
    }
    // 取客户机0号端口
    file://********************************注意******************************
    file://这里当然可以设置为本地机或其它主机的IP,那样报文将返回到该机IP端口,
    file://实际上这是黑客们惯用的手段之一,即利用报文协议来攻击远程主机
    file://便是利用这样的原理,加上多个无限次的报文攻击即可时远程主机瘫痪
    file://对于将本程序利用于非法的攻击活动,笔者概不负责!!!!!!!!!!!!!!!!
    file://******************************************************************
    EndPoint clientPoint = (EndPoint)new IPEndPoint(clientInfo.AddressList[0], 0);       

    file://设置ICMP报文
    int DataSize = 32; // ICMP数据包大小;
    int PacketSize = DataSize + 8;//总报文长度
        const int ICMP_ECHO = 8;
    IcmpPacket packet = new IcmpPacket(ICMP_ECHO,0,0,45,0,DataSize);
                
    Byte [] Buffer = new Byte[ PacketSize ];
    int index=packet.ConvertToByte(Buffer);
    file://报文出错
    if( index != PacketSize)
    {
      Console.WriteLine("There is something wrong with Packet Data !");
      return ;
    }

    int cksum_buffer_length =(int)Math.Ceiling( ((Double)index)/ 2);

    UInt16 [] cksum_buffer = new UInt16[cksum_buffer_length];

    int icmp_header_buffer_index = 0;
    for( int i = 0; i < cksum_buffer_length; i++ )
    {
        file://将两个byte转化为一个UInt16
          cksum_buffer[i] = BitConverter.ToUInt16(Buffer,icmp_header_buffer_index);
          icmp_header_buffer_index += 2;
    }

    file://将校验和保存至报文里
    packet.CheckSum =IcmpPacket.SumOfCheck(cksum_buffer);
    // 保存校验和后,再次将报文转化为数据包
    Byte [] SendData = new Byte[ PacketSize ];
    index= packet.ConvertToByte(SendData);
    file://报文出错
    if( index != PacketSize)
    {
      Console.WriteLine("There is something wrong with Packet Data !");
      return ;
    }
                   

    int nBytes=0;
    file://系统计时开始
    int startTime = Environment.TickCount;
    file://发送数据包
    if ((nBytes = socket.SendTo(SendData, PacketSize, SocketFlags.None,(EndPoint) hostPoint)) == -1)
    {       
      Console.WriteLine("Socket can not send packet");
    }


    Byte [] ReceiveData = new Byte[256];     file://接收数据
    nBytes = 0;

    int timeout=0 ;
    int timeConsume=0;

    while(true)
    {
      nBytes = socket.ReceiveFrom(ReceiveData, 256,SocketFlags.None,ref clientPoint);
      if (nBytes == -1)
      {
        Console.WriteLine("Host not Responding") ;
        break;
      }
      else if(nBytes>0)
      {
        timeConsume = System.Environment.TickCount - startTime;
        Console.WriteLine("Reply from "+hostPoint.ToString()+" in "
        +timeConsume+"MS :Bytes Received"+nBytes);
        break;
      }
      timeConsume=Environment.TickCount - startTime;
      if(timeout>1000)
      {
        Console.WriteLine("Time Out") ;
        break;
      }
        }
               
    file://关闭套接字
    socket.Close();    
      }
   }

    public class IcmpPacket
    {
       private Byte  _type;            // 报文类型
       private Byte  _subCode;        // 字代码类型
       private UInt16 _checkSum;       // 报文校验和
       private UInt16 _identifier;      // 识别符
       private UInt16 _sequenceNumber;     // 序列号 
       private Byte [] _data;         file://数据包

    ///***********************************************************
    ///初始化报文
    ///***********************************************************
    public IcmpPacket(Byte type,Byte subCode,UInt16 checkSum,UInt16 identifier,UInt16 sequenceNumber,int dataSize)
    {
        _type=type;
        _subCode=subCode;
        _checkSum=checkSum;
        _identifier=identifier;
        _sequenceNumber=sequenceNumber;
        _data=new Byte[dataSize];
        for (int i = 0; i < dataSize; i++)
        {
              _data[i] = (byte)'#';
        }
          }
    public UInt16 CheckSum
    {
        get
        {
            return _checkSum;
        }
        set
        {
            _checkSum=value;
        }
    }
       
      ///************************************************************
      ///将整个ICMP报文信息和数据转化为Byte数据包   
      ///************************************************************
      public int ConvertToByte(Byte[] buffer)
      {

    Byte [] b_type = new Byte[1]{_type};
    Byte [] b_code = new Byte[1]{_subCode};
    Byte [] b_cksum = BitConverter.GetBytes(_checkSum);
    Byte [] b_id = BitConverter.GetBytes(_identifier);
    Byte [] b_seq = BitConverter.GetBytes(_sequenceNumber);
           
    int i=0;

    Array.Copy( b_type, 0, buffer, i, b_type.Length );
    i+= b_type.Length;
           
    Array.Copy( b_code, 0, buffer, i, b_code.Length );
    i+= b_code.Length;

    Array.Copy( b_cksum, 0, buffer,i, b_cksum.Length );
    i += b_cksum.Length;

    Array.Copy( b_id, 0, buffer, i, b_id.Length );
    i+= b_id.Length;

    Array.Copy( b_seq, 0, buffer, i, b_seq.Length );
    i += b_seq.Length;

    Array.Copy(_data, 0, buffer, i, _data.Length );
    i += _data.Length;

    return i;

      }
      public static UInt16 SumOfCheck( UInt16[] buffer )
      {
    int cksum = 0;
    for(int i=0;i<buffer.Length;i++)
      cksum += (int) buffer[i];

    cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >> 16);
    return (UInt16)(~cksum);
     
      }


    }

}
 


Tags:

作者:佚名

文章评论评论内容只代表网友观点,与本站立场无关!

   评论摘要(共 0 条,得分 0 分,平均 0 分) 查看完整评论
PB创新网ourmis.com】Copyright © 2000-2009 . All Rights Reserved .
页面执行时间:6,906.25000 毫秒
Email:ourmis@126.com QQ:2322888 蜀ICP备05006790号