J'essaie de créer une application qui analyse un réseau pour les demandes ARP et répertorie tous les périphériques réseau existants. Actuellement, j'utilise SharpPcap
et PacketDoNet
.Prévention des exceptions lors de la résolution du nom d'hôte
Lors de la résolution du nom d'hôte en fonction de l'adresse IP donnée, j'obtiens un SocketException
lors de la résolution d'un hôte "inconnu". J'ai donc mis ceci dans un essai/catch. Puisque je pense que c'est un mauvais style (pour ignorer les exceptions), je cherche une solution différente.
Voici un code:
// Button for scanning the network
private void btnStartScanningForClients_Click(object sender, RoutedEventArgs e)
{
// Check for correct interface
// [...]
// Start scanning process
if (!this.netWorkItOut.Startet)
{
// Dis-/Enable visual controls
// [...]
// Start scanning
var index = this.cbNetworkInterface.SelectedIndex
this.netWorkItOut.StartDevice(index);
this.netWorkItOut.Scanner.StartScanningNetwork(resolveHostnames);
}
}
Ceci est l'objet de contrôle, qui détient le scanner, prend en charge des événements, accepte les paquets et les met dans une file d'attente
public void StartDevice(int deviceIndex)
{
this.Startet = true;
// [...]
this.Device = WinPcapDeviceList.Instance[deviceIndex];
// Activate Scanner
this.Scanner = new Scanner(this.DeviceInfo);
// Subscribe Events
// [...]
this.Device.Open(DeviceMode.Promiscuous, 1);
this.Device.Filter = "(arp || ip || ip6)";
this.Device.OnPacketArrival += device_OnPacketArrival;
this.Device.StartCapture();
}
private void device_OnPacketArrival(object sender, CaptureEventArgs e)
{
//PacketDoNet
Packet packet;
try
{ packet = Packet.ParsePacket(LinkLayers.Ethernet, e.Packet.Data); }
catch (Exception)
{ return; }
if (packet is EthernetPacket)
{
var arp = ARPPacket.GetEncapsulated(packet);
if (arp != null)
{
if (this.Scanner.Started)
{
lock (this.Scanner.PacketQueueARP)
{
this.Scanner.PacketQueueARP.Add(arp);
}
}
}
}
}
C'est Contrôle de l'objet et de la classe Scanner. La classe du scanner fonctionne les requêtes ARP et résout le hostname
public void StartScanningNetwork(bool resolveHostnames)
{
// [...]
this.ResolveHostnames = resolveHostnames;
// start worker to listen for ARP packets
this.workerARP = new Thread(WorkerARP);
this.workerARP.Name = "Scanner thread (ARP)";
this.workerARP.Start();
this.Started = true;
}
private void WorkerARP()
{
List<IPAddress> processedIps = new List<IPAddress>();
// copy packets from storage queue to thread queue for processing
while (Started)
{
// [...]
if (this.threadQueueARP.Count > 0)
{
foreach (var packet in this.threadQueueARP)
{
// [...]
if (!processedIps.Contains(ip))
{
// [...]
if (this.ResolveHostnames)
{
var resolveHostnamesTask = Task.Factory.StartNew(ResolveHostnamesWorker, ip);
}
}
// [...]
}
// [...]
}
// [...]
}
}
private void ResolveHostnamesWorker(object data)
{
if (data is IPAddress)
{
var ip = (IPAddress)data;
var hostname = "";
try
{
hostname = Dns.GetHostEntry(ip).HostName;
}
catch { }
// Raise Event for hostname resolved
}
}
Son tout sur la ligne hostname = Dns.GetHostEntry(ip).HostName
donc: Comment puis-je éviter d'utiliser un try/catch pour résoudre un HostEntry via Dns.GetHostEntry()? Y a-t-il une fonction qui renvoie simplement null
s'il n'y a pas d'hôte connu?
Merci d'avance! Pour autant que je sache, il n'y a pas de méthode comme TryGetHostName() qui ne déclencherait pas d'exception.
étant donné que la capture d'exceptions est un processus fastidieux, cela devrait être ma dernière option. Mais s'il n'y a pas d'autre moyen, je dois le faire de cette façon. Merci pour votre réponse! – Radinator