Есть ли у кого-нибудь код С#, удобный для выполнения ping и traceroute на целевом компьютере? Я ищу чистое решение для кода, а не то, что я сейчас делаю, что вызывает программу ping.exe и tracert.exe и анализирует вывод. Я хотел бы что-то более надежное.
TraceRoute и Ping в С#
Ответ 1
Хотя библиотека базового класса включает Ping, BCL не включает никаких функций tracert.
Однако, быстрый поиск показывает две попытки с открытым исходным кодом, первый в С# второй в С++:
Ответ 2
Учитывая, что мне пришлось написать класс TraceRoute сегодня, я решил, что могу поделиться исходным кодом.
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Text;
using System.Net;
namespace Answer
{
public class TraceRoute
{
private const string Data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
public static IEnumerable<IPAddress> GetTraceRoute(string hostNameOrAddress)
{
return GetTraceRoute(hostNameOrAddress, 1);
}
private static IEnumerable<IPAddress> GetTraceRoute(string hostNameOrAddress, int ttl)
{
Ping pinger = new Ping();
PingOptions pingerOptions = new PingOptions(ttl, true);
int timeout = 10000;
byte[] buffer = Encoding.ASCII.GetBytes(Data);
PingReply reply = default(PingReply);
reply = pinger.Send(hostNameOrAddress, timeout, buffer, pingerOptions);
List<IPAddress> result = new List<IPAddress>();
if (reply.Status == IPStatus.Success)
{
result.Add(reply.Address);
}
else if (reply.Status == IPStatus.TtlExpired || reply.Status == IPStatus.TimedOut)
{
//add the currently returned address if an address was found with this TTL
if (reply.Status == IPStatus.TtlExpired) result.Add(reply.Address);
//recurse to get the next address...
IEnumerable<IPAddress> tempResult = default(IEnumerable<IPAddress>);
tempResult = GetTraceRoute(hostNameOrAddress, ttl + 1);
result.AddRange(tempResult);
}
else
{
//failure
}
return result;
}
}
}
И версия VB для тех, кто хочет/нуждается в ней
Public Class TraceRoute
Private Const Data As String = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
Public Shared Function GetTraceRoute(ByVal hostNameOrAddress As String) As IEnumerable(Of IPAddress)
Return GetTraceRoute(hostNameOrAddress, 1)
End Function
Private Shared Function GetTraceRoute(ByVal hostNameOrAddress As String, ByVal ttl As Integer) As IEnumerable(Of IPAddress)
Dim pinger As Ping = New Ping
Dim pingerOptions As PingOptions = New PingOptions(ttl, True)
Dim timeout As Integer = 10000
Dim buffer() As Byte = Encoding.ASCII.GetBytes(Data)
Dim reply As PingReply
reply = pinger.Send(hostNameOrAddress, timeout, buffer, pingerOptions)
Dim result As List(Of IPAddress) = New List(Of IPAddress)
If reply.Status = IPStatus.Success Then
result.Add(reply.Address)
ElseIf reply.Status = IPStatus.TtlExpired Then
'add the currently returned address
result.Add(reply.Address)
'recurse to get the next address...
Dim tempResult As IEnumerable(Of IPAddress)
tempResult = GetTraceRoute(hostNameOrAddress, ttl + 1)
result.AddRange(tempResult)
Else
'failure
End If
Return result
End Function
End Class
Ответ 3
Ответ 4
Вот как реализовать трассировку http://coding.infoconex.com/post/2009/01/C-Traceroute-using-net-framework.aspx
и еще один способ реализации Ping. http://coding.infoconex.com/post/2009/01/C-Ping-and-Traceroute.aspx
Вышеупомянутое повторяет то же поведение, что и ping windows и traceroute, и его очень просто реализовать.
Ответ 5
Посмотрите -
http://www.codeproject.com/KB/IP/Tracert-ping.aspx
Если вы можете позволить себе платить, сетевые виджеты Dart довольно хороши:
http://www.dart.com/ctl_tracenet.aspx
Здесь есть еще одна реализация халявы:
http://www.digigrupp.com/ping/ и здесь http://www.mltek.co.uk/traceclass.aspx
Ответ 6
Далее следует значительно более эффективная реализация С# tracert
, чем в других ответах до сих пор.
public static IEnumerable<IPAddress> GetTraceRoute(string hostname)
{
// following are the defaults for the "traceroute" command in unix.
const int timeout = 10000;
const int maxTTL = 30;
const int bufferSize = 32;
byte[] buffer = new byte[bufferSize];
new Random().NextBytes(buffer);
Ping pinger = new Ping();
for (int ttl = 1; ttl <= maxTTL; ttl++)
{
PingOptions options = new PingOptions(ttl, true);
PingReply reply = pinger.Send(hostname, timeout, buffer, options);
if (reply.Status == IPStatus.Success)
{
// Success means the tracert has completed
yield return reply.Address;
break;
}
if (reply.Status == IPStatus.TtlExpired)
{
// TtlExpired means we've found an address, but there are more addresses
yield return reply.Address;
continue;
}
if (reply.Status == IPStatus.TimedOut)
{
// TimedOut means this ttl is no good, we should continue searching
continue;
}
// if we reach here, it a status we don't recognize and we should exit.
break;
}
}
Ловушки, исправленные здесь, которые присутствуют в других ответах, включают:
- Это лениво. Пример: он правильно использует перечислимый/итератор, поэтому не нужно вычислять все дерево, вы можете остановиться в любой момент, вырвавшись из своего собственного цикла потребления.
-
maxTTL
реализовано так, что функция не вращается навсегда. -
bufferSize
, который согласуется с другими реализациями tracert. - Это супер кратким и чистым. Он содержится в одном методе и значительно короче, чем другие варианты здесь.
Ответ 7
Я бы начал искать их в пространстве имен System.Net
Ответ 8
Этот разрешает проблему ping без использования стороннего
http://www.aspnettutorials.com/tutorials/network/net-ping-aspnet2-csharp.aspx
Ответ 9
Как явствует из вышеприведенного кода Скотта, я обнаружил, что его решение не работает, если маршрут не сходит в ничто до достижения цели - он никогда не возвращается. Лучшим решением, по крайней мере, с частичным маршрутом, может быть это (которое я тестировал, и он работает хорошо). Вы можете изменить "20" в цикле for на что-то большее или меньшее или попытаться определить, слишком ли оно занимает слишком много времени, если вы хотите каким-то другим способом контролировать количество итераций. Полный кредит Скотту за оригинальный код - спасибо.
using System.Collections.Generic;
using System.Net.NetworkInformation;
using System.Text;
using System.Net;
...
public static void TraceRoute(string hostNameOrAddress)
{
for (int i = 1; i < 20; i++)
{
IPAddress ip = GetTraceRoute(hostNameOrAddress, i);
if(ip == null)
{
break;
}
Console.WriteLine(ip.ToString());
}
}
private static IPAddress GetTraceRoute(string hostNameOrAddress, int ttl)
{
const string Data = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa";
Ping pinger = new Ping();
PingOptions pingerOptions = new PingOptions(ttl, true);
int timeout = 10000;
byte[] buffer = Encoding.ASCII.GetBytes(Data);
PingReply reply = default(PingReply);
reply = pinger.Send(hostNameOrAddress, timeout, buffer, pingerOptions);
List<IPAddress> result = new List<IPAddress>();
if (reply.Status == IPStatus.Success || reply.Status == IPStatus.TtlExpired)
{
return reply.Address;
}
else
{
return null;
}
}