
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
|