Hm. Konen skulle lige se lidt mere film. So here it comes:
using System;
using System.Net;
using System.Net.Sockets;
class Test
{
public static void Main(string[] args)
{
Console.WriteLine(Ping.PingHost("192.168.1.10", 50, 4, 1000));
Console.WriteLine(Ping.PingHost("192.168.1.20", 50, 4, 1000));
Console.WriteLine(Ping.PingHost("
www.microsoft.com", 50, 4, 1000));
Console.WriteLine(Ping.PingHost("
www.not.exist", 50, 4, 1000));
}
}
/// <summary>
/// The Main Ping Class
/// </summary>
public class Ping
{
//Declare some Constant Variables
const int SOCKET_ERROR = -1;
const int ICMP_ECHO = 8;
/// <summary>
/// This method takes the "hostname" of the server
/// and then it ping's it and shows the response time
/// </summary>
public static double PingHost(string strPingHost, int iPingBytes, uint lngPingCount, uint lngPingTimeout)
{
const int MAX_PACKET_SIZE = 65535;
//Declare the IPHostEntry
IPHostEntry PingTarget, PingSource;
int iBytesReceived = 0;
int dwStart = 0, dwStop = 0;
uint iLoop = 0;
bool bContinuous = false;
// Get the server endpoint
try
{
PingTarget = Dns.GetHostByName(strPingHost);
}
catch(Exception)
{
return -1;
}
// Convert the server IP_EndPoint to an EndPoint
IPEndPoint ipepServer = new IPEndPoint(PingTarget.AddressList[0],0);
EndPoint epServer = (ipepServer);
// Set the receiving endpoint to the client machine
PingSource = Dns.GetHostByName(Dns.GetHostName());
IPEndPoint ipEndPointFrom = new IPEndPoint(PingSource.AddressList[0],0);
EndPoint EndPointFrom = (ipEndPointFrom);
int iPacketSize = 0;
IcmpPacket PingPacket = new IcmpPacket();
// Construct the packet to send
PingPacket.Type = ICMP_ECHO; //8
PingPacket.SubCode = 0;
PingPacket.CheckSum = UInt16.Parse("0");
PingPacket.Identifier = UInt16.Parse("45");
PingPacket.SequenceNumber = UInt16.Parse("0");
PingPacket.Data = new Byte[iPingBytes];
//Initialize the Packet.Data
for (int iCount = 0; iCount < iPingBytes; iCount++)
{
PingPacket.Data[iCount] = (byte)'#';
}
//Variable to hold the total Packet size
iPacketSize = iPingBytes + 8;
byte [] bytPktBuffer = new byte[iPacketSize];
int iResult = 0;
//Call a Method Serialize which counts
//The total number of Bytes in the Packet
iResult = Serialize(PingPacket, bytPktBuffer, iPacketSize, iPingBytes );
//Error in Packet Size
if( iResult == -1 )
{
return -1;
}
/* now get this critter into a ushort array */
ushort [] cksum_buffer = new ushort[Convert.ToInt32( Math.Ceiling( Convert.ToDouble(iResult) / 2))];
//Code to initialize the ushort array
int icmp_header_buffer_index = 0;
for( int iCount = 0; iCount < cksum_buffer.Length; iCount++ )
{
cksum_buffer[iCount] = BitConverter.ToUInt16(bytPktBuffer, icmp_header_buffer_index);
icmp_header_buffer_index += 2;
}
//Call a method which will return a checksum
//Save the checksum to the Packet
PingPacket.CheckSum = CheckSum(cksum_buffer);
// Now that we have the checksum, serialize the packet again
byte [] byteSendBuffer = new byte[ iPacketSize ];
//again check the PingPacket size
iResult = Serialize(PingPacket, byteSendBuffer, iPacketSize, iPingBytes );
//if there is a error report it
if( iResult == -1 )
{
return -1;
}
//check for continuous
if (lngPingCount == 0) bContinuous = true;
//Loop the ping
long lngPacketsSent = 0, lngPacketsReceived = 0, lngTotalTransmitTime = 0;
int iMinTransmitTime = int.MaxValue, iMaxTransmitTime = int.MinValue;
do
{
bool bReceived = false ;
//Initialize a Socket of the Type ICMP
Socket PingSocket = new Socket(AddressFamily.InterNetwork, SocketType.Raw, ProtocolType.Icmp);
//Set socket timeout, but this doesn't seem to work...
PingSocket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.ReceiveTimeout, (int) lngPingTimeout);
PingSocket.SetSocketOption( SocketOptionLevel.Socket, SocketOptionName.SendTimeout, (int) lngPingTimeout);
// Initialize the buffers. The receive buffer is the size of the
// ICMP header plus the IP header (20 bytes)
byte [] ReceiveBuffer = new byte [MAX_PACKET_SIZE];
dwStart = System.Environment.TickCount; // Start timing
//Gather stats
lngPacketsSent ++;
//send the Pack over the socket
iResult = PingSocket.SendTo(byteSendBuffer, iPacketSize, SocketFlags.None , epServer);
if ((iResult) == SOCKET_ERROR)
{
return -1;
}
//Receive the bytes
iBytesReceived = 0;
//loop while waiting checking the time of the server responding
while(!bReceived)
{
try
{
iBytesReceived = PingSocket.ReceiveFrom(ReceiveBuffer, MAX_PACKET_SIZE, SocketFlags.None, ref EndPointFrom);
}
catch //(Exception e)
{
bReceived = false;
break;
}
if (iBytesReceived == SOCKET_ERROR)
{
bReceived = false;
break;
}
else if (iBytesReceived > 0)
{
bReceived = true;
dwStop = System.Environment.TickCount - dwStart; // stop timing
//Check for timeout
if ( dwStop > lngPingTimeout)
{
bReceived = false;
System.Threading.Thread.Sleep(System.TimeSpan.FromMilliseconds(1000));
break;
}
break;
}
}//while
//Gather stats
if (bReceived)
{
lngPacketsReceived++;
lngTotalTransmitTime += dwStop;
if (dwStop > iMaxTransmitTime) iMaxTransmitTime = dwStop;
if (dwStop < iMinTransmitTime) iMinTransmitTime = dwStop;
}
iLoop++;
if (bReceived &
(bContinuous | (iLoop < lngPingCount))) //not last ping
{
System.Threading.Thread.Sleep(System.TimeSpan.FromMilliseconds(1000));
}
//close the socket
PingSocket.Shutdown(SocketShutdown.Both);
PingSocket.Close();
} while (bContinuous | (iLoop < lngPingCount)); //Do
if (lngPacketsReceived == 0)
{
return -1;
}
else
{
return ((double) (lngTotalTransmitTime/lngPacketsReceived));
}
}
/// <summary>
/// This method is used to get the Packet and calculates the total size
/// of the Pack by converting it to byte array
/// </summary>
public static int Serialize(IcmpPacket ThisPacket, byte[] Buffer, int PacketSize, int PingData )
{
int cbReturn = 0;
// serialize the struct into the array
int iIndex = 0;
byte [] b_type = new byte[1];
b_type[0] = ThisPacket.Type;
byte [] b_code = new byte[1];
b_code[0] = ThisPacket.SubCode;
byte [] b_cksum = BitConverter.GetBytes(ThisPacket.CheckSum);
byte [] b_id = BitConverter.GetBytes(ThisPacket.Identifier);
byte [] b_seq = BitConverter.GetBytes(ThisPacket.SequenceNumber);
// Console.WriteLine("Serialize type ");
Array.Copy( b_type, 0, Buffer, iIndex, b_type.Length );
iIndex += b_type.Length;
// Console.WriteLine("Serialize code ");
Array.Copy( b_code, 0, Buffer, iIndex, b_code.Length );
iIndex += b_code.Length;
// Console.WriteLine("Serialize cksum ");
Array.Copy( b_cksum, 0, Buffer, iIndex, b_cksum.Length );
iIndex += b_cksum.Length;
// Console.WriteLine("Serialize id ");
Array.Copy( b_id, 0, Buffer, iIndex, b_id.Length );
iIndex += b_id.Length;
Array.Copy( b_seq, 0, Buffer, iIndex, b_seq.Length );
iIndex += b_seq.Length;
// copy the data
Array.Copy( ThisPacket.Data, 0, Buffer, iIndex, PingData );
iIndex += PingData;
if( iIndex != PacketSize/* sizeof(IcmpPacket) */)
{
cbReturn = -1;
return cbReturn;
}
cbReturn = iIndex;
return cbReturn;
}
/// <summary>
/// Checksum -
/// Algorithm to create a checksup for a buffer
/// </summary>
public static ushort CheckSum( ushort[] BufferToChecksum )
{
int iCheckSum = 0;
for (uint iCount = 0; iCount < BufferToChecksum.Length; iCount++)
{
iCheckSum += Convert.ToInt32( BufferToChecksum[iCount] );
}
iCheckSum = (iCheckSum >> 16) + (iCheckSum & 0xffff);
iCheckSum += (iCheckSum >> 16);
return (ushort)(~iCheckSum);
}
/// <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 ushort CheckSum; // ones complement checksum of struct
public ushort Identifier; // identifier
public ushort SequenceNumber; // sequence number
public byte[] Data; // byte array of data
} // class IcmpPacket
} // class ping