Este artigo descreve a implementação de um scanner de sinal WiFi em C# que detecta a intensidade do sinal, estima distâncias e monitora redes em tempo real.
Implementação do Componente Principal
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Timers;
using SimpleWifi;
public class MonitorDeSinalWifi : IDisposable
{
private Wifi _servicoWifi;
private Timer _temporizador;
private Dictionary<string distancia="" double="" sinal=""> _resultados = new();
public event EventHandler<atualizacaoresultadoseventargs> ResultadosAtualizados;
public MonitorDeSinalWifi()
{
_servicoWifi = new Wifi();
ConfigurarTemporizador(5000);
}
private void ConfigurarTemporizador(int intervalo)
{
_temporizador = new Timer(intervalo);
_temporizador.Elapsed += async (s, e) => await RealizarVarredura();
}
private async Task RealizarVarredura()
{
try
{
var pontosDeAcesso = await _servicoWifi.ObterPontosDeAcessoAsync();
var listaDeResultados = new List<resultadoscan>();
foreach (var ponto in pontosDeAcesso)
{
if (ponto.ForcaSinal > -100)
{
double distanciaEstimada = EstimarDistancia(ponto.ForcaSinal);
listaDeResultados.Add(new ResultadoScan
{
Rede = ponto.Nome,
Sinal = ponto.ForcaSinal,
Distancia = distanciaEstimada,
Canal = ponto.Canal,
Seguro = ponto.EhSeguro
});
}
}
_resultados = listaDeResultados.ToDictionary(r => r.Rede, r => (r.Sinal, r.Distancia));
ResultadosAtualizados?.Invoke(this, new AtualizacaoResultadosEventArgs(listaDeResultados));
}
catch (Exception ex)
{
RegistrarErro(ex);
}
}
private double EstimarDistancia(int sinal)
{
const double distanciaReferencia = 1.0;
const int sinalReferencia = -30;
if (sinal >= sinalReferencia) return 0.1;
double perdaCaminho = sinalReferencia - sinal;
return Math.Pow(10, perdaCaminho / 20) * distanciaReferencia;
}
public void ExibirResultados()
{
Console.WriteLine("Resultados da Varredura de WiFi:");
foreach (var item in _resultados.Values)
{
Console.WriteLine($"Rede: {item.Rede,-15} " +
$"Sinal: {item.Sinal}dBm " +
$"Distância: {item.Distancia:F1}m " +
$"Canal: {item.Canal} " +
$"Segurança: {(item.Seguro ? "Sim" : "Não")}");
}
}
public void Dispose()
{
_temporizador?.Dispose();
_servicoWifi?.Dispose();
}
}
public class ResultadoScan
{
public string Rede { get; set; }
public int Sinal { get; set; }
public double Distancia { get; set; }
public int Canal { get; set; }
public bool Seguro { get; set; }
}
public class AtualizacaoResultadosEventArgs : EventArgs
{
public List<resultadoscan> Resultados { get; }
public AtualizacaoResultadosEventArgs(List<resultadoscan> resultados)
{
Resultados = resultados;
}
}
</resultadoscan></resultadoscan></resultadoscan></atualizacaoresultadoseventargs></string>
Detalhes das Funcionalidades Chave
1. Detecção de Intensidade de Sinal
var pontosDeAcesso = await _servicoWifi.ObterPontosDeAcessoAsync();
foreach (var ponto in pontosDeAcesso)
{
Console.WriteLine($"Rede: {ponto.Nome}");
Console.WriteLine($"Intensidade: {ponto.ForcaSinal}%");
Console.WriteLine($"Valor dBm: {ConverterParaDbm(ponto.ForcaSinal)}dBm");
}
private int ConverterParaDbm(int porcentagem)
{
return (int)((porcentagem / 2.0) - 100);
}
2. Algoritmo de Estimativa de Distância
private double EstimarDistanciaAprimorada(int sinal)
{
const double potenciaTransmissao = -59;
const double expoentePerda = 2.7;
double razao = sinal * 1.0 / potenciaTransmissao;
if (razao < 1) return Math.Pow(razao, 10);
else return 0.89976 * Math.Pow(razao, 7.7095) + 0.111;
}
3. Interface de Monitoramento em Tempo Real (Exemplo com WinForm)
public partial class FormularioPrincipal : Form
{
private MonitorDeSinalWifi _monitor;
private DataGridView _gradeDeDados;
public FormularioPrincipal()
{
InitializeComponent();
InicializarComponentes();
_monitor = new MonitorDeSinalWifi();
_monitor.ResultadosAtualizados += AoAtualizarResultados;
}
private void InicializarComponentes()
{
_gradeDeDados = new DataGridView { Dock = DockStyle.Fill };
_gradeDeDados.Columns.AddRange(
new DataGridViewTextBoxColumn { Name = "Rede", HeaderText = "Nome da Rede" },
new DataGridViewTextBoxColumn { Name = "IntensidadeSinal", HeaderText = "Sinal (dBm)" },
new DataGridViewTextBoxColumn { Name = "Distancia", HeaderText = "Distância (m)" }
);
Controls.Add(_gradeDeDados);
}
private void AoAtualizarResultados(object sender, AtualizacaoResultadosEventArgs e)
{
_gradeDeDados.Invoke((MethodInvoker)delegate {
_gradeDeDados.DataSource = e.Resultados;
});
}
}
Práticas de Engenharia
1. Configuração de Permissões
<!-- app.manifest -->
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
2. Otimização de Desempenho
- Varrredura em Lote: Combine múltiplas varreduras para reduzir chamadas ao sistema.
- Cache de Dados: Use
ConcurrentDictionarypara armazenar dados históricos. - Processamento Assíncrono: Empregue
async/awaitpara evitar travamentos na interface.
3. Extensões de Funcionalidades Avançadas
public Dictionary<int, int> AnalisarUtilizacaoDeCanais()
{
return _resultados.Values
.GroupBy(r => r.Canal)
.ToDictionary(g => g.Key, g => g.Count());
}
public Bitmap GerarMapaDeCalor()
{
// Implementação usando GDI+ para visualizar a distribuição de sinal.
}
Implantação e Uso
1. Dependências via NuGet
Install-Package SimpleWifi.netstandard.Lsh
Install-Package LiveCharts.WinForms
2. Exemplo de Execução
var scanner = new MonitorDeSinalWifi();
scanner.ResultadosAtualizados += (s, e) =>
{
Console.WriteLine($"Detectados {e.Resultados.Count} redes");
e.Resultados.OrderByDescending(r => r.Sinal).Take(3).ToList().ForEach(r =>
Console.WriteLine($"Sinal mais forte: {r.Rede} ({r.Sinal}dBm)"));
};
scanner.IniciarVarreduraContinua();
Depuração e Calibração
1. Registro de Logs
public static class Registrador
{
public static void RegistrarDadosDeSinal(int sinal, double distancia)
{
File.AppendAllText("registro_wifi.txt",
$"{DateTime.Now:yyyy-MM-dd HH:mm:ss} | Sinal:{sinal} | Distância:{distancia}m\n");
}
}
2. Calibração de Precisão
private static double _fatorCalibracao = 1.2;
public double DistanciaCalibrada(int sinal)
{
double distanciaBruta = EstimarDistancia(sinal);
return distanciaBruta * _fatorCalibracao;
}
Sugestões para Aprimoramento da Interface
1. Visualização de Intensidade de Sinal
var grafico = new CartesianChart();
grafico.Series = new SeriesCollection
{
new LineSeries
{
Values = new ChartValues<double>(_resultados.Values.Select(r => (double)r.Sinal))
}
};
2. Funcionalidade de Localização de Dispositivos
public Point CalcularPosicao()
{
var pontosDeAcesso = _resultados.Values.ToList();
if (pontosDeAcesso.Count < 3) return Point.Empty;
// Implementação do algoritmo de trilateração...
}