Avatar billede omen Nybegynder
12. oktober 2003 - 20:28 Der er 12 kommentarer og
1 løsning

Ping info på en form!

Når jeg skal spille online, plejer jeg altid lige at tjekke om jeg har en go' ping, før jeg starter spillet! Så jeg går ned i Kør, og skriver:
ping opasia.dk
så jeg kan se om det er en ping der er værd at spille med!
Er der en måde at få den information ind på en C# form?
F.eks, en textbox hvor jeg skriver url, and Button, så når jeg trykker på den, viser den min ping i en label!
Avatar billede arne_v Ekspert
12. oktober 2003 - 20:34 #1
Der er noget kode her:
  http://www.csharphelp.com/archives2/files/archive296/ping.cs
som du relativt nemt burde kunne bruge i din form.
Avatar billede arne_v Ekspert
12. oktober 2003 - 20:35 #2
(bare ignorer alt command line parsingen og kald PingHost med
whatever)
Avatar billede omen Nybegynder
12. oktober 2003 - 22:13 #3
Jeg tager lige et kig på det!
Avatar billede omen Nybegynder
12. oktober 2003 - 22:28 #4
Det kan jeg sgu umiddelbart ikke lige finde ud af!
Avatar billede arne_v Ekspert
12. oktober 2003 - 22:33 #5
Du henter den klasse, fjerner console mode hoved-programmet og
erstatter console output med f.eks. at returnere en streng.

Virker det ikke ?

Eller er det omskrivningen der driller ? (der er en del linier
kode i en ping !)
Avatar billede omen Nybegynder
12. oktober 2003 - 23:09 #6
Det er nok omskrivningen... det er lige over min skill *L*
Avatar billede arne_v Ekspert
12. oktober 2003 - 23:11 #7
Jeg prøver at skrive den om til en ikke console afhængig metode
som returnerer ping tid.

OK ?

Men det bliver først imorgen aften - jeg er på vej i seng !
Avatar billede omen Nybegynder
12. oktober 2003 - 23:16 #8
Ja det lyder for lækkert!

Bare sig til hvis det kræver flere point :)
Avatar billede arne_v Ekspert
12. oktober 2003 - 23:45 #9
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
Avatar billede arne_v Ekspert
12. oktober 2003 - 23:45 #10
Output fra test kørsel:

11
-1
66
-1

(jeg returnerer -1 for fejl)
Avatar billede arne_v Ekspert
12. oktober 2003 - 23:46 #11
Du kalder bare Ping.PingHost med de rigtige argumenter og får
et resultat tilbage.
Avatar billede arne_v Ekspert
12. oktober 2003 - 23:46 #12
Jeg har kun lige rettet koden til så den virker.

Den kunne pyntes en hel del !
Avatar billede arne_v Ekspert
12. oktober 2003 - 23:47 #13
Du må da godt smide lidt ekstra point.

Men de oprindelige 60 point er også helt OK.
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
IT-kurser om Microsoft 365, sikkerhed, personlig vækst, udvikling, digital markedsføring, grafisk design, SAP og forretningsanalyse.

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester