Ping через заданное устройство - C#

Узнай цену своей работы

Формулировка задачи:

У меня два интернета. Один через роутер, другой через usb. Использую пинг для проверки соединения. Проблема в том, что не знаю как отправить пинг через нужное мне устройство. Допустим интернет в данный момент работает через роутер, а мне нужно проверить его через модем или наоборот.
Листинг программы
  1. public static bool Ping()
  2. {
  3. var status = IPStatus.Unknown;
  4. var ip = "85.113.32.176";
  5. PingReply pr = new Ping().Send(@ip);
  6. if (status == IPStatus.Success) return true; // интернет есть
  7. return false; // интернета нет
  8. }

Решение задачи: «Ping через заданное устройство»

textual
Листинг программы
  1. public static PingReply Send(IPAddress srcAddress, IPAddress destAddress, int timeout = 5000, byte[] buffer = null, PingOptions po = null)
  2. {
  3.     if (destAddress == null || destAddress.AddressFamily != AddressFamily.InterNetwork || destAddress.Equals(IPAddress.Any))
  4.         throw new ArgumentException();
  5.  
  6.     //Defining pinvoke args
  7.     var source = srcAddress == null ? 0 : BitConverter.ToUInt32(srcAddress.GetAddressBytes(), 0);
  8.     var destination = BitConverter.ToUInt32(destAddress.GetAddressBytes(), 0);
  9.     var sendbuffer = buffer ?? new byte[] {};
  10.     var options = new Interop.Option
  11.     {
  12.         Ttl = (po == null ? (byte) 255 : (byte) po.Ttl),
  13.         Flags = (po == null ? (byte) 0 : po.DontFragment ? (byte) 0x02 : (byte) 0) //0x02
  14.     };
  15.     var fullReplyBufferSize = Interop.ReplyMarshalLength + sendbuffer.Length; //Size of Reply struct and the transmitted buffer length.
  16.  
  17.  
  18.  
  19.     var allocSpace = Marshal.AllocHGlobal(fullReplyBufferSize); // unmanaged allocation of reply size. TODO Maybe should be allocated on stack
  20.     try
  21.     {
  22.         DateTime start = DateTime.Now;
  23.         var nativeCode = Interop.IcmpSendEcho2Ex(
  24.             Interop.IcmpHandle, //_In_      HANDLE IcmpHandle,
  25.             default(IntPtr), //_In_opt_  HANDLE Event,
  26.             default(IntPtr), //_In_opt_  PIO_APC_ROUTINE ApcRoutine,
  27.             default(IntPtr), //_In_opt_  PVOID ApcContext
  28.             source, //_In_      IPAddr SourceAddress,
  29.             destination, //_In_      IPAddr DestinationAddress,
  30.             sendbuffer, //_In_      LPVOID RequestData,
  31.             (short) sendbuffer.Length, //_In_      WORD RequestSize,
  32.             ref options, //_In_opt_  PIP_OPTION_INFORMATION RequestOptions,
  33.             allocSpace, //_Out_     LPVOID ReplyBuffer,
  34.             fullReplyBufferSize, //_In_      DWORD ReplySize,
  35.             timeout //_In_      DWORD Timeout
  36.             );
  37.         TimeSpan duration = DateTime.Now - start;
  38.         var reply = (Interop.Reply) Marshal.PtrToStructure(allocSpace, typeof (Interop.Reply)); // Parse the beginning of reply memory to reply struct
  39.  
  40.         byte[] replyBuffer = null;
  41.         if (sendbuffer.Length != 0)
  42.         {
  43.             replyBuffer = new byte[sendbuffer.Length];
  44.             Marshal.Copy(allocSpace + Interop.ReplyMarshalLength, replyBuffer, 0, sendbuffer.Length); //copy the rest of the reply memory to managed byte[]
  45.         }
  46.  
  47.         if (nativeCode == 0) //Means that native method is faulted.
  48.             return new PingReply(nativeCode, reply.Status, new IPAddress(reply.Address), duration);
  49.         else
  50.             return new PingReply(nativeCode, reply.Status, new IPAddress(reply.Address), reply.RoundTripTime, replyBuffer);
  51.     }
  52.     finally
  53.     {
  54.         Marshal.FreeHGlobal(allocSpace); //free allocated space
  55.     }
  56. }
  57.  
  58. /// <summary>Interoperability Helper
  59. ///     <see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/bb309069(v=vs.85).aspx" />
  60. /// </summary>
  61. private static class Interop
  62. {
  63.     private static IntPtr? icmpHandle;
  64.     private static int? _replyStructLength;
  65.  
  66.     /// <summary>Returns the application legal icmp handle. Should be close by IcmpCloseHandle
  67.     ///     <see cref="http://msdn.microsoft.com/en-us/library/windows/desktop/aa366045(v=vs.85).aspx" />
  68.     /// </summary>
  69.     public static IntPtr IcmpHandle
  70.     {
  71.         get
  72.         {
  73.             if (icmpHandle == null)
  74.             {
  75.                 icmpHandle = IcmpCreateFile();
  76.                 //TODO Close Icmp Handle appropiate
  77.             }
  78.  
  79.             return icmpHandle.GetValueOrDefault();
  80.         }
  81.     }
  82.     /// <summary>Returns the the marshaled size of the reply struct.</summary>
  83.     public static int ReplyMarshalLength
  84.     {
  85.         get
  86.         {
  87.             if (_replyStructLength == null)
  88.             {
  89.                 _replyStructLength = Marshal.SizeOf(typeof (Reply));
  90.             }
  91.             return _replyStructLength.GetValueOrDefault();
  92.         }
  93.     }
  94.  
  95.  
  96.     [DllImport("Iphlpapi.dll", SetLastError = true)]
  97.     private static extern IntPtr IcmpCreateFile();
  98.     [DllImport("Iphlpapi.dll", SetLastError = true)]
  99.     private static extern bool IcmpCloseHandle(IntPtr handle);
  100.     [DllImport("Iphlpapi.dll", SetLastError = true)]
  101.     public static extern uint IcmpSendEcho2Ex(IntPtr icmpHandle, IntPtr Event, IntPtr apcroutine, IntPtr apccontext, UInt32 sourceAddress, UInt32 destinationAddress, byte[] requestData, short requestSize, ref Option requestOptions, IntPtr replyBuffer, int replySize, int timeout);
  102.     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  103.     public struct Option
  104.     {
  105.         public byte Ttl;
  106.         public readonly byte Tos;
  107.         public byte Flags;
  108.         public readonly byte OptionsSize;
  109.         public readonly IntPtr OptionsData;
  110.     }
  111.     [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
  112.     public struct Reply
  113.     {
  114.         public readonly UInt32 Address;
  115.         public readonly int Status;
  116.         public readonly int RoundTripTime;
  117.         public readonly short DataSize;
  118.         public readonly short Reserved;
  119.         public readonly IntPtr DataPtr;
  120.         public readonly Option Options;
  121.     }
  122. }
  123.  
  124. [Serializable]
  125. public class PingReply
  126. {
  127.     private readonly byte[] _buffer = null;
  128.     private readonly IPAddress _ipAddress = null;
  129.     private readonly uint _nativeCode = 0;
  130.     private readonly TimeSpan _roundTripTime = TimeSpan.Zero;
  131.     private readonly IPStatus _status = IPStatus.Unknown;
  132.     private Win32Exception _exception;
  133.  
  134.  
  135.     internal PingReply(uint nativeCode, int replystatus, IPAddress ipAddress, TimeSpan duration)
  136.     {
  137.         _nativeCode = nativeCode;
  138.         _ipAddress = ipAddress;
  139.         if (Enum.IsDefined(typeof (IPStatus), replystatus))
  140.             _status = (IPStatus) replystatus;
  141.     }
  142.     internal PingReply(uint nativeCode, int replystatus, IPAddress ipAddress, int roundTripTime, byte[] buffer)
  143.     {
  144.         _nativeCode = nativeCode;
  145.         _ipAddress = ipAddress;
  146.         _roundTripTime = TimeSpan.FromMilliseconds(roundTripTime);
  147.         _buffer = buffer;
  148.         if (Enum.IsDefined(typeof (IPStatus), replystatus))
  149.             _status = (IPStatus) replystatus;
  150.     }
  151.  
  152.  
  153.     /// <summary>Native result from <code>IcmpSendEcho2Ex</code>.</summary>
  154.     public uint NativeCode
  155.     {
  156.         get { return _nativeCode; }
  157.     }
  158.     public IPStatus Status
  159.     {
  160.         get { return _status; }
  161.     }
  162.     /// <summary>The source address of the reply.</summary>
  163.     public IPAddress IpAddress
  164.     {
  165.         get { return _ipAddress; }
  166.     }
  167.     public byte[] Buffer
  168.     {
  169.         get { return _buffer; }
  170.     }
  171.     public TimeSpan RoundTripTime
  172.     {
  173.         get { return _roundTripTime; }
  174.     }
  175.     /// <summary>Resolves the <code>Win32Exception</code> from native code</summary>
  176.     public Win32Exception Exception
  177.     {
  178.         get
  179.         {
  180.             if (Status != IPStatus.Success)
  181.                 return _exception ?? (_exception = new Win32Exception((int) NativeCode, Status.ToString()));
  182.             else
  183.                 return null;
  184.         }
  185.     }
  186.  
  187.     public override string ToString()
  188.     {
  189.         if (Status == IPStatus.Success)
  190.             return Status + " from " + IpAddress + " in " + RoundTripTime + " ms with " + Buffer.Length + " bytes";
  191.         else if (Status != IPStatus.Unknown)
  192.             return Status + " from " + IpAddress;
  193.         else
  194.             return Exception.Message + " from " + IpAddress;
  195.     }
  196. }

ИИ поможет Вам:


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

Оцени полезность:

8   голосов , оценка 4.25 из 5

Нужна аналогичная работа?

Оформи быстрый заказ и узнай стоимость

Бесплатно
Оформите заказ и авторы начнут откликаться уже через 10 минут
Похожие ответы