2010-08-06 4 views
0

J'ai un serveur public (configuré avec indy 10). certains clients inconnus envoient des milliers de messages sans contenu qui modifient l'utilisation du processeur du serveur à 50%. je n'ai pas de pare-feu sur mon serveur, donc j'ai essayé de bloquer les clients inconnus avec ce code:comment bloquer les clients inconnus dans indy (Delphi)

Ceci est une fonction qui fonctionne avec une minuterie:

var 
    i, j: integer; 
begin 
    IX2 := IX2 + 1; 
    SetLength(ClientIPs, IX2); 
    ClientIPs[IX2 - 1] := StrIP; 
    j := 0; 
    for i := low(ClientIPs) to high(ClientIPs) do 
    begin 
    Application.ProcessMessages; 
    if ClientIPs[i] = StrIP then 
     j := j + 1; 
    end; 
    if j > 10 then 
    begin 
    Result := false; 
    exit; 
    end; 
    Result := true; 

Et c'est mon code Timer:

//Reset filtering measures 
    IX2 := 0; 
    SetLength(ClientIPs, 0); 

donc je peux l'utiliser dans l'événement OnExecute:

LogIP := AContext.Connection.Socket.Binding.PeerIP; 

    if IPFilter(LogIP) <> true then 
    begin 
    AContext.Connection.disconnect; 
    exit; 
    end; 

    //Get Data ********* 
    Data := AContext.Connection.IOHandler.ReadLn(); 

enfin, si un client envoie l'homme y message dans un court laps de temps, il sera déconnecté. Mais il y a un problème . En fait, après la déconnexion du client, l'événement Onexecute fonctionne toujours et je ne peux pas arrêter l'opération. En tout cas, j'ai besoin de bloquer complètement certaines adresses IP.

Merci

+0

On dirait que vous avez besoin d'un pare-feu. Pourquoi ne pas en utiliser un? –

+0

Donc, je ne peux pas résoudre ce problème: (après la déconnexion du client, l'événement Onexecute fonctionne toujours). n'est-ce pas? – Kermia

+0

Application.ProcessMessages demande des problèmes. Pourquoi est-ce là? –

Répondre

4

à Followup mon commentaire précédent:

function TForm1.IPFilter(const StrIP: string): Boolean; 
var 
    i, j: integer; 
    list: TList; 
begin 
    j := 0; 
    list := IdTCPServer1.Contexts.LockList; 
    try 
    for i := 0 to list.Count-1 do 
    begin 
     if TIdContext(list[i]).Binding.PeerIP = StrIP then 
     Inc(j); 
    end; 
    Result := j <= 10; 
    finally 
    IdTCPServer1.Contexts.UnlockList; 
    end; 
end; 

procedure TForm1.IdTCPServer1Execute(AContext: TIdContext); 
begin 
    // the simpliest way to force a disconnect and stop 
    // the calling thread is to raise an exception... 
    if not IPFilter(AContext.Binding.PeerIP) then 
    Abort(); 

    // alternatively, if you call Disconnect(), make sure 
    // the IOHandler's InputBuffer is empty, or else 
    // AContext.Connection.Connected() will continue 
    // returning True!... 
    {if not IPFilter(AContext.Binding.PeerIP) then 
    begin 
    AContext.Connection.Disconnect; 
    AContext.Connection.IOHandler.InputBuffer.Clear; 
    Exit; 
    end;} 

    //Get Data ********* 
    Data := AContext.Connection.IOHandler.ReadLn(); 
end; 
+0

Merci Monsieur Lebeau – Kermia

5

L'événement OnConnect serait un meilleur endroit pour déconnecter les adresses IP mis à l'index. La seule raison pour effectuer la vérification dans l'événement OnExecute est que l'adresse IP n'est pas mise en liste noire tant que OnConnect n'a pas été déclenché. Pour savoir pourquoi OnExecute continue à fonctionner après vous être déconnecté, la seule solution possible est que votre gestionnaire OnExecute dispose d'un bloc try..except interceptant et ignorant les notifications internes d'Indy. Toute exception de gestion que vous faites doit sur-relancer les exceptions dérivées de EIdException afin que le serveur puisse les traiter.

+0

Salut, Merci pour la réponse. mais je n'utilise pas essayer/sauf! – Kermia

+0

Ensuite, veuillez indiquer votre code OnExecute actuel. Vous ne manipulez pas correctement les déconnexions. –

+0

Salut, j'ai fait Mr Lebeau. ceci est mon code OnExecute: LogIP: = AContext.Connection.Socket.Binding.PeerIP; si IPFilter (LogIP) <> true alors commencer AContext.Connection.disconnect; sortie; fin; // Obtenir des données ********* Data: = AContext.Connection.IOHandler.ReadLn(); Alors, comment puis-je gérer les déconnexions correctement? Merci – Kermia