bueno, hola a todos, pues tengo una duda, hice una clase para evitar el envio masivo de paquetes de datos a un servidor de una aplicacion que hago, ya que produciria retraso en la respuesta para los otros clientes, pasa que quiero saber si la clase que hice serviria en cierto modo para detener eso, tengo fe en que si, no lo he probado si funciona como deberia, pero me parece que si, pasa que si lo probara en mi pc, el resultado seria optimo(creo yo), quiero saber si en realidad serviria frente a varios clientes verdaderos.
public class Entry
{
public DateTime lastTry;
public IClient client;
public Entry(IClient arg)
{
lastTry = DateTime.Now;
client = arg;
}
public void Disconnect()
{
client.Disconnect();
}
}
/// <summary>
/// Clase usada para evitar el envio masivo de bytes desde los clientes que no
/// sean el que se esta manipulando.
///
/// </summary>
public class Anti_Flooding
{
//Indica si el Anti-Flooding esta funcionando
static bool IsWorking;
//Medido en segundos, es la cantidad minima de segundos que debe esperar cada
//cliente para enviar otro packet
const int minConnectionSleep = 3;
//Medido en minutos, es la cantidad de minutos que no se aceptaran conexiones
//desde el cliente que este ban
const int BannedTime = 5;
static Thread BannedsRemover;
/// <summary>
/// IP vs Client
/// </summary>
static SafeDictionary<string, Entry> Entries = new SafeDictionary<string, Entry>();
static SafeDictionary<string, Entry> Banneds = new SafeDictionary<string, Entry>();
/// <summary>
/// revisa si el IClient esta ban, en caso de estarlo lo desconecta y devuelve true
/// </summary>
/// <param name="arg">ICliente al que se le revisara Ban</param>
/// <returns></returns>
public static bool isBanned(IClient arg)
{
if (Banneds.ContainsKey(arg.IP))
{
arg.Disconnect();
return true;
}
return false;
}
public static void Try(IClient arg)
{
if (!IsWorking)
return;
if (!Entries.ContainsKey(arg.IP))
{
Entry entry = new Entry(arg);
Entries.Add(arg.IP, entry);
}
else
{
Entry entry = Entries[arg.IP];
if (entry.lastTry.AddSeconds(minConnectionSleep) > DateTime.Now)
{
entry.Disconnect();
Entries.Remove(arg.IP);
Banneds.Add(arg.IP, entry);
}
}
}
public static void StartAntiFlooding()
{
BannedsRemover = new Thread(new ThreadStart(RemoveBanneds));
BannedsRemover.Start();
IsWorking = true;
}
public static void StopAntiFlooding()
{
BannedsRemover.Abort();
IsWorking = false;
if (Banneds.Count > 0)
{
foreach (Entry entry in Banneds.Values)
{
Entries.Add(entry.client.IP, entry);
Banneds.Remove(entry.client.IP);
}
}
}
static void RemoveBanneds()
{
while (true)
{
foreach (Entry entry in Banneds.Values)
{
if (entry.lastTry.AddMinutes(BannedTime) <= DateTime.Now)
{
string IP = entry.client.IP;
Banneds.Remove(IP);
Entries.Add(IP, entry);
}
}
Thread.Sleep(20000);
}
}
}
en caso de que si sirva y alguien lo quiera usar de verdad, deberan implementar en la clase que tienen como cliente la interfaz IClient
public interface IClient
{
void Disconnect();
string IP { get; }
}
la clase SafeDictionary es solo un simplificador de ConcurrentDictionary para que funcione como Dictionary y poder cambiarlo rapidamente en sources que descargaba con mas de un hilo/thread
public class SafeDictionary<TKey, TValue> : ConcurrentDictionary<TKey, TValue>
{
public bool Add(TKey Key, TValue value)
{
return base.TryAdd(Key, value);
}
public new TValue this[TKey key]
{
get
{
TValue value = default(TValue);
base.TryGetValue(key, out value);
return value;
}
set
{
base.TryUpdate(key, value, this[key]);
}
}
public bool Remove(TKey key)
{
TValue value;
return base.TryRemove(key, out value);
}
de antemano gracias