发信人: youngplayer (youngplayer), 信区: Npsos
标  题: ping by c#
发信站: 哈工大紫丁香 (Tue May 20 16:19:03 2003) , 转信

/* Ping.cs 
 * file to demonstrate the implementation of Ping in C#
 * It needs some Intermediate knowledge of how Ping works
 * I have used the example provided in MSDN Magazine by Lance Olson 
 * and modified it to suit by requirememnts
 * Compile Statement
 * csc /r:System.dll;System.Net.dll Ping.cs
 * 
 * Saurabh Nandu
 * 15/02/2001
 */
namespace SaurabhPing
{
    using System;
    using System.Net;
using System.Net.Sockets;
/// <summary>
/// The Main Ping Class
/// </summary>
class Ping
{
//Declare some Constant Variables
    const int SOCKET_ERROR = -1;        
    const int ICMP_ECHO = 8;
/// <summary>
/// The Starting Point of the Class
/// It Takes the Hostname parameter
/// </summary>
public static void Main(string[] argv)
{
if(argv.Length==0)
{
//If user did not enter any Parameter inform him
Console.WriteLine("Usage:Ping <hostname> /r") ;
Console.WriteLine("<hostname> The name of the Host who you want to ping");

Console.WriteLine("/r Optional Switch to Ping the host continuously") ;
}
else if(argv.Length==1)
{
//Just the hostname provided by the user
//call the method "PingHost" and pass the HostName as a parameter
PingHost(argv[0]) ;
}
else if(argv.Length==2)
{
//the user provided the hostname and the switch
if(argv[1]=="/r")
{
//loop the ping program
while(true)
{
//call the method "PingHost" and pass the HostName as a parameter
PingHost(argv[0]) ;
}
}
else
{
//if the user provided some other switch
PingHost(argv[0]) ;
}

}
else
{
//Some error occured
Console.WriteLine("Error in Arguments") ;
}
}

/// <summary>
/// This method takes the "hostname" of the server
/// and then it ping's it and shows the response time
/// </summary>
public static void PingHost(string host)
{
//Declare the IPHostEntry 
        IPHostEntry serverHE, fromHE;
        int nBytes = 0;
        int dwStart = 0, dwStop = 0;
        //Initilize a Socket of the Type ICMP
Socket socket = new Socket(AddressFamily.AfINet, SocketType.SockRaw, Protoc
olType.ProtICMP);

        // Get the server endpoint
try
{
serverHE = DNS.GetHostByName(host);
}
        catch(Exception)
{
Console.WriteLine("Host not found"); // fail
return ;
}

        // Convert the server IP_EndPoint to an EndPoint
        IPEndPoint ipepServer = new IPEndPoint(serverHE.AddressList[0], 0);
        EndPoint epServer = (ipepServer);

// Set the receiving endpoint to the client machine
        fromHE = DNS.GetHostByName(DNS.GetHostName());
        IPEndPoint ipEndPointFrom = new IPEndPoint(fromHE.AddressList[0], 0);
        
        EndPoint EndPointFrom = (ipEndPointFrom);

        int PacketSize = 0;
IcmpPacket packet = new IcmpPacket();
        // Construct the packet to send
        packet.Type = ICMP_ECHO; //8
        packet.SubCode = 0;
        packet.CheckSum = UInt16.Parse("0");
        packet.Identifier   = UInt16.Parse("45"); 
        packet.SequenceNumber  = UInt16.Parse("0"); 
int PingData = 32; // sizeof(IcmpPacket) - 8;
        packet.Data = new Byte[PingData];
//Initilize the Packet.Data
        for (int i = 0; i < PingData; i++)
{
packet.Data[i] = (byte)'#';
}
             
//Variable to hold the total Packet size
        PacketSize = PingData + 8;
        Byte [] icmp_pkt_buffer = new Byte[ PacketSize ]; 
        Int32 Index = 0;
//Call a Methos Serialize which counts
//The total number of Bytes in the Packet
        Index = Serialize(  
                      packet, 
                      icmp_pkt_buffer, 
                      PacketSize, 
                      PingData );
//Error in Packet Size
        if( Index == -1 )
{
Console.WriteLine("Error in Making Packet");
return ;
}
          
            // now get this critter into a UInt16 array
         
            //Get the Half size of the Packet
            Double double_length = Convert.ToDouble(Index);
            Double dtemp = Math.Ceil( double_length / 2);
int cksum_buffer_length = Convert.ToInt32(dtemp);
            //Create a Byte Array
            UInt16 [] cksum_buffer = new UInt16[cksum_buffer_length];
//Code to initilize 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_i
ndex);
                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 )
{
Console.WriteLine("Error in Making Packet");
return ;
}
                

            dwStart = System.Environment.TickCount; // Start timing
//send the Pack over the socket
            if ((nBytes = socket.SendTo(sendbuf, PacketSize, 0, epServer)) ==
 SOCKET_ERROR) 
{
                Console.WriteLine("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) 
{
Console.WriteLine("Host not Responding") ;
recd=true ;
break;
}
else if(nBytes>0)
{
dwStop = System.Environment.TickCount - dwStart; // stop timing
Console.WriteLine("Reply from "+epServer.ToString()+" in "+dwStop+"MS :B
ytes Received"+nBytes);
recd=true;
break;
}
timeout=System.Environment.TickCount - dwStart;
if(timeout>1000)
{
Console.WriteLine("Time Out") ;
recd=true;
}

}
            
//close the socket
        socket.Close();     
}
/// <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 Pac
ketSize, 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);
        
        // Console.WriteLine("Serialize type ");
        Array.Copy( b_type, 0, Buffer, Index, b_type.Length );
        Index += b_type.Length;
        
        // Console.WriteLine("Serialize code ");
        Array.Copy( b_code, 0, Buffer, Index, b_code.Length );
        Index += b_code.Length;

        // Console.WriteLine("Serialize cksum ");
        Array.Copy( b_cksum, 0, Buffer, Index, b_cksum.Length );
        Index += b_cksum.Length;

        // Console.WriteLine("Serialize id ");
        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 += Convert.ToInt32( buffer[counter] );
        counter += 1;
        size -= 1;
    }

        cksum = (cksum >> 16) + (cksum & 0xffff);
    cksum += (cksum >> 16);
    return (UInt16)(~cksum);
}
} // class ping
/// <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
}



--

※ 来源:.哈工大紫丁香 http://bbs.hit.edu.cn [FROM: 202.118.239.62]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:213.885毫秒