Модераторы: Partizan, gambit
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Пинг прозводится не корректно, Пингую в 2-х потоках, 2 разл устройства 
:(
    Опции темы
CYBERDREAM
Дата 18.2.2008, 15:40 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I think, there4 I am
***


Профиль
Группа: Завсегдатай
Сообщений: 1096
Регистрация: 31.10.2006
Где: CyberLand

Репутация: 11
Всего: 28



Доброго времени суток всем.
Вообщем проблема такова:
В одном потоке пингую принтер (соединение с которым имеется). В др. потоке 2-е устройство которое не подключено и должно выдавать 100% потерь. 
Если пинг обоих устройств происходит в разное время, все хорошо. Но если это происходит в одно и то же время, то пинг до второго устройства выдает 0% потерь, будто бы оно подключено. В чем может заключаться проблемка?

Пинг, осуществляется с помощью следующего класса:
Код

using System;
using System.Net;
using System.Net.Sockets;

namespace Ping
{
 /// <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[] args)
   {
     string strHostToPing = "";
     bool   bLoop = false;
     bool   bAddressResolve = false;
     int    iBytes = 32;
     uint   lngCount = 4;
     uint   lngTimeout = 1000;

     if(args.Length == 0)
     {
       //If user did not enter any Parameter inform him
       Console.WriteLine("Usage: Ping [-t] [-a] [-l size] [-n count] [-w timeout] <hostname> ");
       Console.WriteLine("<hostname> The name of the Host who you want to ping");
       Console.WriteLine("Options:");
       Console.WriteLine("    -t             Ping the specified host until stopped.");
       Console.WriteLine("    -a             Resolve addresses to hostnames.");
       Console.WriteLine("    -n count       Number of echo requests to send.");
       Console.WriteLine("    -l size        Send buffer size.");
       Console.WriteLine("    -w timeout     Timeout in milliseconds to wait for each reply.");
       return;
     }

     for (int iCount=0; iCount < args.Length; iCount++) 
     {
       string temp = args[iCount];
       switch (temp.ToLower()) 
       {
         case "-t":
           bLoop = true;
           break;

         case "-a":
           bAddressResolve = true;
           break;

         case "-l":
           iCount++;
           try 
           {
             //Next arg s/b an int
             iBytes = Int32.Parse(args[iCount]);
             if (iBytes < 0 | iBytes > 65500)
             {
               Console.WriteLine("Bad value for option -l, valid range is from 0 to 65500.");
               return;
             }
           }
           catch 
           {
             Console.WriteLine("Bad value for option -l, valid range is from 0 to 65500.");
             return;
           }
           break;

         case "-n":
           iCount++;
           try 
           {
             //Next arg s/b an int
             lngCount = UInt32.Parse(args[iCount]);
             if (lngCount  < 0 | lngCount  > UInt32.MaxValue)
             {
               Console.WriteLine("Bad value for option -n, valid range is from 0 to {0}.",UInt32.MaxValue);
               return;
             }
           }
           catch 
           {
             Console.WriteLine("Bad value for option -n, valid range is from 0 to {0}.",UInt32.MaxValue);
             return;
           }
           break;
           
         case "-w":
           iCount++;
           try 
           {
             //Next arg s/b an int
             lngTimeout = UInt32.Parse(args[iCount]);
             if (lngTimeout  < 1 | lngTimeout  > UInt32.MaxValue)
             {
               Console.WriteLine("Bad value for option -w, valid range is from 1 to {0}.",UInt32.MaxValue);
               return;
             }
           }
           catch 
           {
             Console.WriteLine("Bad value for option -w, valid range is from 1 to {0}.",UInt32.MaxValue);
             return;
           }
           break;
         default:
           strHostToPing = temp;
           break;
       }
     }

     //Check for continuous
     if (bLoop) lngCount = 0;

     //Do the ping
     PingHost(strHostToPing, iBytes, lngCount, lngTimeout );
   }

   /// <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 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;
     //Random ICMP identification.
     // This fixes the bug where this ICMP would listen to all ICMP transmits
     Random        rndIdent = new Random();
     ushort        iIdent = (ushort) rndIdent.Next(ushort.MaxValue);

     // Get the server endpoint
     try
     {
       PingTarget = Dns.GetHostByName(strPingHost);
     }
     catch(Exception)
     {
       Console.WriteLine("Unkown host {0}" , strPingHost); // fail
       return;
     }

     // 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);

     Console.WriteLine("\nPinging {0} [{1}] with {2} bytes of data:\n", strPingHost, 
       ipepServer.Address.ToString(), iPingBytes);

     //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;
     ushort iSeq = 0;
     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 ++;


       //Create the next packet in our sequence
       IcmpPacket PingPacket = new IcmpPacket();
       if (!GetICMPPacket(PingPacket, iIdent, iSeq++, iPingBytes) )
       {
         Console.WriteLine("Error in Making Packet");
         return;
       }
       int iPacketSize = iPingBytes + 8;
       // Move this ICMPPacket into a byte buffer
       byte [] byteSendBuffer = new byte[ iPacketSize ];
       //serialize this PingPacket into a byte array
       int iResult = 0;
       iResult = Serialize(PingPacket, byteSendBuffer, iPacketSize, iPingBytes );
       if( iResult == -1 )//if there is a error report it
       {
         Console.WriteLine("Error in Making Packet");
         return;
       }

       //send the Packet over the socket
       iResult = PingSocket.SendTo(byteSendBuffer, iPacketSize, SocketFlags.None , epServer);
       if ((iResult) == SOCKET_ERROR)
       {
         Console.WriteLine("Socket Error cannot Send Packet");
       }
       //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)
         {
           //Console.WriteLine ("Request timed out. \n{0}", e.Message);
           Console.WriteLine ("Request timed out.");
           bReceived = false;
           break;
         }
         //OK, check the ident & seq
         int iTemp = ReceiveBuffer[25] * 256 + ReceiveBuffer[24];
         ushort iRecIdent = (ushort) iTemp;
         iTemp = ReceiveBuffer[27] * 256 + ReceiveBuffer[26];
         ushort iRecSeq   = (ushort) iTemp;
         if ( (iRecIdent != iIdent) || (iRecSeq != (iSeq-1)) )   //Not our packet
         {   
           Console.WriteLine ("Request timed out.");
           bReceived = false;
           break;
         }


         if (iBytesReceived == SOCKET_ERROR)
         {
           Console.WriteLine("Host not Responding");
           bReceived = false;
           break;
         } 
         else if (iBytesReceived > 0) 
         {

           bReceived = true;
           dwStop = System.Environment.TickCount - dwStart; // stop timing

           //Check for timeout
           if ( dwStop > lngPingTimeout)
           {
             Console.WriteLine ("Request timed out.");
             bReceived = false;
             System.Threading.Thread.Sleep(System.TimeSpan.FromMilliseconds(1000));
             break;
           }
           if (dwStop < 10) 
           {
             Console.WriteLine("Reply from {0}: bytes: {1} time:<10ms ({2})", ipepServer.Address.ToString(), iBytesReceived - 28, iRecSeq);
           } 
           else 
           {
             Console.WriteLine("Reply from {0}: bytes: {1} time: {2}ms ({3})", ipepServer.Address.ToString(), iBytesReceived - 28, dwStop, iRecSeq);
           }
           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


     //Report stats
     Console.WriteLine("\nPing statistics for {0}", ipepServer.Address.ToString());
     if (lngPacketsSent == 0) 
     {
       Console.WriteLine("    Packets: Sent = {0}, Received = {1}, Lost = {2} ({3}% loss),", lngPacketsSent, lngPacketsReceived, lngPacketsSent-lngPacketsReceived, 0 );
     } 
     else
     {
       Console.WriteLine("    Packets: Sent = {0}, Received = {1}, Lost = {2} ({3}% loss),", lngPacketsSent, lngPacketsReceived, lngPacketsSent-lngPacketsReceived, ((double) (lngPacketsSent-lngPacketsReceived)/lngPacketsSent)* 100 );
     }
     Console.WriteLine("Approximate round trip times in milli-seconds:");
     if (lngPacketsReceived == 0) 
     {
       Console.WriteLine("    Minimum = {0}ms, Maximum =  {1}ms, Average =  {2}ms", 0, 0, 0 );
     } 
     else
     {
       Console.WriteLine("    Minimum = {0}ms, Maximum =  {1}ms, Average =  {2}ms", iMinTransmitTime, iMaxTransmitTime,(int) ((double) (lngTotalTransmitTime/lngPacketsReceived)) );
     }
     return;
   }

   
   /// <summary>
   ///  This method creates an ICMP Packet
   /// </summary>
   public static bool GetICMPPacket(IcmpPacket PingPacket, ushort Identifier, ushort SequenceNumber, int PingBytes)
   {
     int iPacketSize = 0;

     // Construct the packet to send
     PingPacket.Type = ICMP_ECHO; //8
     PingPacket.SubCode = 0; 
     PingPacket.CheckSum = UInt16.Parse("0");
     PingPacket.Identifier   = Identifier;
     PingPacket.SequenceNumber  = SequenceNumber;
     PingPacket.Data = new Byte[PingBytes];
     //Initialize the Packet.Data
     for (int iCount = 0; iCount < PingBytes; iCount++)
     {
       PingPacket.Data[iCount] = (byte)'#';
     }

     //Variable to hold the total Packet size
     iPacketSize = PingBytes + 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, PingBytes );
     if( iResult == -1 )//Error in Packet Size
     {
       Console.WriteLine("Error in Making Packet");
       return false;
     }

     // 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 and save the checksum to the Packet
     PingPacket.CheckSum = CheckSum(cksum_buffer);

     return true;
   }
   
   /// <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
}



--------------------
Ищем .Net, Java, Javascript разработчиков, Кипр, Лимассол. (знание английского необязательно)
Telegram, skype: kuchuk.artiom
PM MAIL WWW   Вверх
Crimp
Дата 18.2.2008, 18:35 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 21.10.2007
Где: Tula

Репутация: 1
Всего: 2



Лажа тут
Код

                   try {
                            iBytesReceived = PingSocket.ReceiveFrom(ReceiveBuffer, MAX_PACKET_SIZE, SocketFlags.None, ref EndPointFrom);
                            Console.WriteLine(EndPointFrom.ToString());
                            Console.WriteLine();
                    }
                    catch //(Exception e)
                    {
                        //Console.WriteLine ("Request timed out. \n{0}", e.Message);
                        Console.WriteLine("Request timed out.");
                        bReceived = false;
                        break;
                    }

поставб бряку на catch, выруби поток который пингует принтер и посмотри, а потом вруби оба потока и сравни результат smile 
PM MAIL ICQ   Вверх
CYBERDREAM
Дата 19.2.2008, 14:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I think, there4 I am
***


Профиль
Группа: Завсегдатай
Сообщений: 1096
Регистрация: 31.10.2006
Где: CyberLand

Репутация: 11
Всего: 28



Прошу прощения, но что значит "поставить бряку"? То бишь закоментировать?
Если убрать try catch то при первой ошибочке пинговать перестает


--------------------
Ищем .Net, Java, Javascript разработчиков, Кипр, Лимассол. (знание английского необязательно)
Telegram, skype: kuchuk.artiom
PM MAIL WWW   Вверх
jorikdima
Дата 19.2.2008, 14:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 107
Регистрация: 18.1.2008
Где: Там, где Зенит

Репутация: нет
Всего: нет



брэйкпоинт smile

точка останова тобишь в дебаггере
PM MAIL   Вверх
CYBERDREAM
Дата 19.2.2008, 15:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I think, there4 I am
***


Профиль
Группа: Завсегдатай
Сообщений: 1096
Регистрация: 31.10.2006
Где: CyberLand

Репутация: 11
Всего: 28



В случае если нет соединения с устройством, он сразу в catch идет. Что с прринтером, что без. Ну и сообщение что 
Цитата

Попытка установить соедение была безуспешной, т.к. от др. компьютера .за требуемое время...



--------------------
Ищем .Net, Java, Javascript разработчиков, Кипр, Лимассол. (знание английского необязательно)
Telegram, skype: kuchuk.artiom
PM MAIL WWW   Вверх
Crimp
Дата 19.2.2008, 23:21 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 21.10.2007
Где: Tula

Репутация: 1
Всего: 2



Ты ставил бряку, ты запускал несколько раз подряд, посмотри там же понятно, что в твоем олгаритме допушенно несколько ошибот как, как когда до 
Код

iBytesReceived = PingSocket.ReceiveFrom(ReceiveBuffer, MAX_PACKET_SIZE, SocketFlags.None, ref EndPointFrom);

первым добирается поток который пигует твой принтер, то вся твоя логика далее идет на....й, прога тебя не наепывает только в том случае когда первым при запуске до этого места добирается поток который пингует несуш устройство, ито это только 1 цикл, далее как только проходит пинг на принтер, прога тебя начинает обманывать, так как логика у тебя на мой взгляд не верна, для того чтоб понять, нужно проделать то что я писал в предыдушем посте.
Разобрался или рассписать подробнее.

Это сообщение отредактировал(а) Crimp - 19.2.2008, 23:45
PM MAIL ICQ   Вверх
CYBERDREAM
Дата 20.2.2008, 00:04 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I think, there4 I am
***


Профиль
Группа: Завсегдатай
Сообщений: 1096
Регистрация: 31.10.2006
Где: CyberLand

Репутация: 11
Всего: 28



Если возможно, то описать по подробнее smile буду весьма признателен


--------------------
Ищем .Net, Java, Javascript разработчиков, Кипр, Лимассол. (знание английского необязательно)
Telegram, skype: kuchuk.artiom
PM MAIL WWW   Вверх
Crimp
Дата 20.2.2008, 00:56 (ссылка) |    (голосов:1) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 21.10.2007
Где: Tula

Репутация: 1
Всего: 2



Рассписать по подробнее смогу только уже сегодня smile но вечером. А так советую всётаки поработать в дебагере. Пока не имея под рукой работаюшего приложения, могу сказать лиш следуюшие. Замени все "Request timed out", на разные сообшения, позапускай прилагу, и оцени, такие ли ты ожидаеш результы. По идее вот в этом коде
Код

iBytesReceived = PingSocket.ReceiveFrom(ReceiveBuffer, MAX_PACKET_SIZE, SocketFlags.None, ref EndPointFrom);

пр и попытке отправки на несушествуюший адрес должно генерироваться исключение, что повторюсь в твоем случае происходит только при запуске 1 потока, пингуюшиго это самое несушествуюшее соединение. При 2 поточном же варианте о чудо, от туда ничинают валить ответы, мне интерестно от куда. С этим я пока не разбирался. 

Это сообщение отредактировал(а) Crimp - 20.2.2008, 00:56
PM MAIL ICQ   Вверх
YuryS
Дата 23.2.2008, 17:31 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 14
Регистрация: 15.9.2007

Репутация: 1
Всего: 1



По-моему, всё работает как надо - вот полный код 2-поточного приложения:
Код

using System;
using System.Net;
using System.Net.Sockets;
using System.Threading;

public class  Ping {

 public static void Main ( String[] args ) {
 
  string strHostToPing1 = "";
  string strHostToPing2 = "";
    
  strHostToPing1 = args [ 0 ];
  strHostToPing2 = args [ 1 ];
  
  ThreadClass tc1 = new ThreadClass ( strHostToPing1 );
  tc1.Run();
  
  ThreadClass tc2 = new ThreadClass ( strHostToPing2 );
  tc2.Run();
   
  Console.ReadKey();
 }
 
}

public class ThreadClass {
 
 const int SOCKET_ERROR = -1;
 const int ICMP_ECHO = 8;
 
 private string strPingHost;
 
 bool   bLoop = false;
 bool   bAddressResolve = false;
 int    iPingBytes = 32;
 uint   lngPingCount = 4;
 uint   lngPingTimeout = 1000;
 
 public ThreadClass ( string strPingHost ) {
  this.strPingHost = strPingHost;
 }
 
 public void Run ( )   {
 
  Thread t = new Thread ( new ThreadStart ( PingHost ) );
  t.Start();
  
 }

 public void PingHost()
 {
     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;
     
     int           iPort = 1001;
     
     //Random ICMP identification.
     // This fixes the bug where this ICMP would listen to all ICMP transmits
     Random        rndIdent = new Random();
     ushort        iIdent = (ushort) rndIdent.Next(ushort.MaxValue);   
     

     // Get the server endpoint
     try
     {
       PingTarget = Dns.GetHostByName(strPingHost);
     }
     catch(Exception)
     {
       Console.WriteLine("Unkown host {0}" , strPingHost); // fail
       return;
     }

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

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

     Console.WriteLine("\nPinging {0} [{1}] with {2} bytes of data:\n", strPingHost,
       ipepServer.Address.ToString(), iPingBytes);

     //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;
     ushort iSeq = 0;
     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 ++;


       //Create the next packet in our sequence
       IcmpPacket PingPacket = new IcmpPacket();
       if (!GetICMPPacket(PingPacket, iIdent, iSeq++, iPingBytes) )
       {
         Console.WriteLine("Error in Making Packet");
         return;
       }
       int iPacketSize = iPingBytes + 8;
       // Move this ICMPPacket into a byte buffer
       byte [] byteSendBuffer = new byte[ iPacketSize ];
       //serialize this PingPacket into a byte array
       int iResult = 0;
       iResult = Serialize(PingPacket, byteSendBuffer, iPacketSize, iPingBytes );
       if( iResult == -1 )//if there is a error report it
       {
         Console.WriteLine("Error in Making Packet");
         return;
       }

       //send the Packet over the socket
       iResult = PingSocket.SendTo(byteSendBuffer, iPacketSize, SocketFlags.None , epServer);
       if ((iResult) == SOCKET_ERROR)
       {
         Console.WriteLine("Socket Error cannot Send Packet");
       }
       //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)
         {
           //Console.WriteLine ("Request timed out. \n{0}", e.Message);
           Console.WriteLine ("Request timed out.");
           bReceived = false;
           break;
         }
         //OK, check the ident & seq
         int iTemp = ReceiveBuffer[25] * 256 + ReceiveBuffer[24];
         ushort iRecIdent = (ushort) iTemp;
         iTemp = ReceiveBuffer[27] * 256 + ReceiveBuffer[26];
         ushort iRecSeq   = (ushort) iTemp;
         if ( (iRecIdent != iIdent) || (iRecSeq != (iSeq-1)) )   //Not our packet
         {
           Console.WriteLine ("Request timed out.");
           bReceived = false;
           break;
         }


         if (iBytesReceived == SOCKET_ERROR)
         {
           Console.WriteLine("Host not Responding");
           bReceived = false;
           break;
         }
         else if (iBytesReceived > 0)
         {

           bReceived = true;
           dwStop = System.Environment.TickCount - dwStart; // stop timing

           //Check for timeout
           if ( dwStop > lngPingTimeout)
           {
             Console.WriteLine ("Request timed out.");
             bReceived = false;
             System.Threading.Thread.Sleep(System.TimeSpan.FromMilliseconds(1000));
             break;
           }
           if (dwStop < 10)
           {
             Console.WriteLine("Reply from {0}: bytes: {1} time:<10ms ({2})", ipepServer.Address.ToString(), iBytesReceived - 28, iRecSeq);
           }
           else
           {
             Console.WriteLine("Reply from {0}: bytes: {1} time: {2}ms ({3})", ipepServer.Address.ToString(), iBytesReceived - 28, dwStop, iRecSeq);
           }
           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


     //Report stats
     Console.WriteLine("\nPing statistics for {0}", ipepServer.Address.ToString());
     if (lngPacketsSent == 0)
     {
       Console.WriteLine("    Packets: Sent = {0}, Received = {1}, Lost = {2} ({3}% loss),", lngPacketsSent, lngPacketsReceived, lngPacketsSent-lngPacketsReceived, 0 );
     }
     else
     {
       Console.WriteLine("    Packets: Sent = {0}, Received = {1}, Lost = {2} ({3}% loss),", lngPacketsSent, lngPacketsReceived, lngPacketsSent-lngPacketsReceived, ((double) (lngPacketsSent-lngPacketsReceived)/lngPacketsSent)* 100 );
     }
     Console.WriteLine("Approximate round trip times in milli-seconds:");
     if (lngPacketsReceived == 0)
     {
       Console.WriteLine("    Minimum = {0}ms, Maximum =  {1}ms, Average =  {2}ms", 0, 0, 0 );
     }
     else
     {
       Console.WriteLine("    Minimum = {0}ms, Maximum =  {1}ms, Average =  {2}ms", iMinTransmitTime, iMaxTransmitTime,(int) ((double) (lngTotalTransmitTime/lngPacketsReceived)) );
     }
     return;
 }
 
 //*********************************************************************************************//
 
 public static bool GetICMPPacket(IcmpPacket PingPacket, ushort Identifier, ushort SequenceNumber, int PingBytes)
   {
     int iPacketSize = 0;

     // Construct the packet to send
     PingPacket.Type = ICMP_ECHO; //8
     PingPacket.SubCode = 0;
     PingPacket.CheckSum = UInt16.Parse("0");
     PingPacket.Identifier   = Identifier;
     PingPacket.SequenceNumber  = SequenceNumber;
     PingPacket.Data = new Byte[PingBytes];
     //Initialize the Packet.Data
     for (int iCount = 0; iCount < PingBytes; iCount++)
     {
       PingPacket.Data[iCount] = (byte)'#';
     }

     //Variable to hold the total Packet size
     iPacketSize = PingBytes + 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, PingBytes );
     if( iResult == -1 )//Error in Packet Size
     {
       Console.WriteLine("Error in Making Packet");
       return false;
     }

     // 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 and save the checksum to the Packet
     PingPacket.CheckSum = CheckSum(cksum_buffer);

     return true;
   }
 
 //************************************************************************************//
 
 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;
   }
   
 //******************************************************************//
 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) + (iCheckSum & 0xffff);
     iCheckSum += (iCheckSum >> 16);
     return (ushort)(~iCheckSum);
 }

 
}

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
}


и вот протокол его запуска (сообщения от 2-ух потоков, естественно, чередуются):

K:\>Ping 193.232.174.28 193.232.174.29

Pinging 193.232.174.29 [193.232.174.29] with 32 bytes of data:


Pinging 193.232.174.28 [193.232.174.28] with 32 bytes of data:

Reply from 193.232.174.28: bytes: 32 time:<10ms (0)
Request timed out.
Request timed out.
Reply from 193.232.174.28: bytes: 32 time:<10ms (1)
Request timed out.
Reply from 193.232.174.28: bytes: 32 time:<10ms (2)
Request timed out.

Ping statistics for 193.232.174.29
    Packets: Sent = 4, Received = 0, Lost = 4 (100% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum =  0ms, Average =  0ms
Reply from 193.232.174.28: bytes: 32 time: 15ms (3)

Ping statistics for 193.232.174.28
    Packets: Sent = 4, Received = 4, Lost = 0 (0% loss),
Approximate round trip times in milli-seconds:
    Minimum = 0ms, Maximum =  15ms, Average =  3ms

Пинговалось 2 компьютера - 28-ой живой,
а 29-й - нет.
PM MAIL   Вверх
CYBERDREAM
Дата 26.2.2008, 14:39 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


I think, there4 I am
***


Профиль
Группа: Завсегдатай
Сообщений: 1096
Регистрация: 31.10.2006
Где: CyberLand

Репутация: 11
Всего: 28



Thx 2 YuryS за изложенный вариант, проверю в ближайшее время.
Вот взял за основу др. класс, пока работает как надо, может кто то сталкивался с ним и знает его недочеты, хотя по идее таковых не должно быть
Код

using System;
using System.Net;
using System.Runtime.InteropServices;

namespace RFID_prj
{
    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct ICMP_ECHO_REPLY
    {
        public uint Address;
        public uint Status;
        public uint RoundTripTime;
        public ushort DataSize;
        public ushort Reserved;
        public IntPtr Data;
        public IP_OPTION_INFORMATION Options;
    }

    [StructLayout(LayoutKind.Sequential, Pack=1)]
    public struct IP_OPTION_INFORMATION
    {
        public byte TTL;
        public byte TOS;
        public byte Flags;
        public byte OptionsSize;
        public IntPtr OptionsData;
        public int RealOptionData;
    }

    public class Icmp
    {
        public const int IP_SUCCESS = 0;
        public const int IP_BUF_TOO_SMALL = 11001;
        public const int IP_REQ_TIMED_OUT = 11010;
        [DllImport("icmp.dll")]
        public static extern IntPtr IcmpCreateFile();
        [DllImport("icmp.dll")]
        public static extern uint IcmpSendEcho(IntPtr icmpHandle, uint
            ipAddr, ref int requestData, ushort requestSize, IntPtr optionInfo, ref
            ICMP_ECHO_REPLY replyBuffer, uint replySize, int timeout);
        [DllImport("icmp.dll")]
        public static extern bool IcmpCloseHandle(IntPtr icmpHandle);
        public static bool Ping(string host)
        {
            uint addr =
                BitConverter.ToUInt32(IPAddress.Parse(host).GetAddressBytes(), 0);
            IntPtr h = IcmpCreateFile();
            int req = 123456789;
            ICMP_ECHO_REPLY rep = new ICMP_ECHO_REPLY();
            uint retval = IcmpSendEcho(h, addr, ref req, 4, IntPtr.Zero,
                ref rep, 32, 10);
            IcmpCloseHandle(h);
            return (retval != 0 && rep.Status == IP_SUCCESS);    
        }
    }
}



--------------------
Ищем .Net, Java, Javascript разработчиков, Кипр, Лимассол. (знание английского необязательно)
Telegram, skype: kuchuk.artiom
PM MAIL WWW   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Прежде чем создать тему, посмотрите сюда:
mr.DUDA
THandle

Используйте теги [code=csharp][/code] для подсветки кода. Используйтe чекбокс "транслит" если у Вас нет русских шрифтов.
Что делать если Вам помогли, но отблагодарить помощника плюсом в репутацию Вы не можете(не хватает сообщений)? Пишите сюда, или отправляйте репорт. Поставим :)
Так же не забывайте отмечать свой вопрос решенным, если он таковым является :)


Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, mr.DUDA, THandle.

 
1 Пользователей читают эту тему (1 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Общие вопросы по .NET и C# | Следующая тема »


 




[ Время генерации скрипта: 0.0944 ]   [ Использовано запросов: 21 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.