Bug sur un code

Résolu
MiniApp Messages postés 654 Date d'inscription lundi 21 juillet 2014 Statut Membre Dernière intervention 22 février 2019 - 4 août 2014 à 11:51
MiniApp Messages postés 654 Date d'inscription lundi 21 juillet 2014 Statut Membre Dernière intervention 22 février 2019 - 8 août 2014 à 10:07
Bonjour je cherche à faire une classe mais j'ai un code qui bug :
Procedure TIPv4.SaveToFileOptimize(FileName:String);
{Enregistre dans le format le plus court
Format (127.0.0.1) :
[SM]Simple(127.0.0.1)->127.0.0.1:Codage standard sans simplification
[S0]Supp0(127.0.0.1)->127...1:Supression des 0
[NP]NoPoint(255.255.255.255)->255255255255:Supprime les points (uniquement si chaque Octect > 99)
[NM]Name(127.0.0.1)->me:Transforme en nom si possible}
Var
Temp:TStrings;
Supp0:ShortString;
NoPoint:ShortString;
Name:ShortString;
Begin
//Préparation
Temp := TStrings.Create;//Initialisation de Temp
//Application des algorithme
  //Supp0
  If FByte1 = 0 Then//Simplique du 1er octect possible?
    Supp0 := '.'
  Else Supp0 := IntToStr(FByte1)+'.';
  If FByte2 = 0 Then//Simplique du 2e octect possible?
    Supp0 := Supp0 + '.'
  Else Supp0 := Supp0 + IntToStr(FByte2)+'.';
  If FByte3 = 0 Then//Simplique du 3e octect possible?
    Supp0 := Supp0 + '.'
  Else Supp0 := Supp0 + IntToStr(FByte3)+'.';
  If FByte4 = 0 Then//Simplique du 4e octect possible?
  Else Supp0 := Supp0 + IntToStr(FByte4);
  //NoPoint
  If (FByte1 > 99) and (FByte2 > 99) and (FByte3 > 99) and (FByte4 > 99) Then
    NoPoint := GetIP('')
  Else NoPoint := GetIP;
  //Name
  NoPoint := GetIP;
  If GetIP = '127.0.0.1' Then
    NoPoint := GetIP('me');
  If GetIP = '255.255.255.255' Then
    NoPoint := GetIP('+');
  If GetIP = '0.0.0.0' Then
    NoPoint := GetIP('-');
  If GetIP = '192.168.1.1' Then
    NoPoint := GetIP('nat1');
  If GetIP = '192.168.0.1' Then
    NoPoint := GetIP('nat0');
  If GetIP = '255.255.255.0' Then
    NoPoint := GetIP('nat');
//Recherche de l'algorithme le plus court
Temp.Text := 'SM' + GetIP;//Simple
 If Length(Supp0) < Length(Temp.Text) Then//Supp0
   Begin
     Temp.Text := 'S0' + Supp0;
   end;
 If Length(NoPoint) < Length(Temp.Text) Then//NoPoint
   Begin
     Temp.Text := 'NP' + NoPoint;
   end;
 If Length(Name) < Length(Temp.Text) Then//Name
   Begin
     Temp.Text := 'NM' + Name;
   end;
//Enregistrement
Temp.SaveToFile(FileName);
end;


Temp.Text := 'SM' + GetIP;
(ligne 48) fait une erreur abstraite (je suis sérieux). Fbyte1, Fbyte2, Fbyte3 et Fbyte4 sont des Byte. GetIP renvoie 127.127.127.127.

Ce code enregistre un IP dans le format le plus court d'après 3 algorithmes différent. Ensuite le code choisit le plus adapter.

Merci de votre aide.

3 réponses

Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
Modifié par Francky23012301 le 4/08/2014 à 12:37
Malheureusement en l'état actuel on ne peut pas tester ton code puisqu'il manque des variables globales dont tu nous donnes pas le type.

Ceci dit quelques remarques en vrac :

-Je crois que tu as mal lu la définition du type ShortString qui est inutile dans ton cas et devenu obsolète avec les dernières versions de delphi (Utilisation de l'unicode).

-On utilise dans la mesure du possible jamais de variables globales. Au pire on réalise une fonction si on a besoin de récupérer un résultat.

-Arrêtte avec ces transtypages systématiques : Ton code est déjà lent à la base, n'en rajoute pas une couche ;).

-Ton code n'est pas optimisé ni en terme d'écriture (Il y a plus simple et plus beau) ni en terme d'execution.
0
MiniApp Messages postés 654 Date d'inscription lundi 21 juillet 2014 Statut Membre Dernière intervention 22 février 2019 5
Modifié par MiniApp le 4/08/2014 à 14:44
Pour ShortString je suis sur Delphi 5 (Borland(c)1999) et son manuel ne spécifie pas d'obselèscence.^^

Question rapidité vu que je l'éxécute qu'une fois je n'ai pas de problèmes, en plus il est instantanément éxécuter (jusqu'a l'erreur).

Plus simple et plus beau je vais essayer (heureusement que j'ai mit des commentaires!).

GetIP renvoie un String (un IPv4 formater normalement). Fbyte1, Fbyte2, Fbyte3 et Fbyte4 sont des Byte
(
Byte=0..255
). Quel autres variables il manque ?
0
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
Modifié par Francky23012301 le 4/08/2014 à 14:55
Petite question : En lisant ton code il ressort que tu essayes de formater les adresses IP en de nouvelles écritures. Je ne vois pas l'intérêt.

-En effet si ce fichier est destiné à l'utilisateur ce dernier sera incompréhensible en l'état pour lui. 127...1 cela ne voudra rien dire pour un utilisateur lambda.

-Si ton objectif est de réutiliser les IP de ce log, tu devras reformater tes IP sous forme standard avant quoi que soit. Cela n'a donc absolument aucun intérêt.


-Pour finir quand on fait ce genre de chose il est toujours conseillé de préciser le type de formatage que l'on a fait

TTypeIp = (Simple,SuppZero,NoPoint,URLName);
TFormatedIP = Record
   TypeIP : TTypeIP;
   IP : String;
End;


Exemple d'utilisation

Function ChangeIp(Const MyIP:String): TFormatedIP;
Begin
  Result.TypeIP:=NoPoint;
  Result.IP:=StringReplace(MyIP,'.','',RfReplaceAll);
End;


L'avantage de cela est que quand on veut retranscrire une IP, on a pas besoin d'analyser le format qui a été utilisé pour faire cette réécriture. Optimiser une application c'est aussi penser à cela ;)
0
MiniApp Messages postés 654 Date d'inscription lundi 21 juillet 2014 Statut Membre Dernière intervention 22 février 2019 5
4 août 2014 à 14:51
Je fait une classe descendant de TPersistent.
J'ai le décodeur que je n'ai qu'a tester.
Cet encodage permet dans le cas d'une liste de gagner des octects ce qui peut dans le cas de longues liste de gagner beaucoup de place sur le disque où dans le RAM.
Voici la déclaration de mon type :
type
  Int0To3=0..3;
  Int1To3=1..3;
  TIPv4 = class(TPersistent)
  private
    { Déclarations privées }
    FByte1:Byte;
    FByte2:Byte;
    FByte3:Byte;
    FByte4:Byte;
  public
    { Déclarations publiques}
    //procedure pour un format xxx.xxx.xxx.xxx
    Function GetIP(SeparatorString:String='.'):String;
    Function SetIP(Adress:String;NbBt1:Int1To3;NbBt2:Int1To3;NbBt3:Int1To3;NbBt4:Int1To3):WordBool;Overload;
    Function SetIP(Adress:String;SeparatorString:String='.'):WordBool;Overload;
    //procedure pour un format Cardinal
    Function GetIPInCardinal:Cardinal;
    Function SetIPWithCardinalAnd3Bytes(Adress:Cardinal;ByteA:Byte;ByteB:Byte;ByteC:Byte;ByteD:Byte;EmptyByte:Int0To3):WordBool;
    //Procedure d'enregistrement
    Procedure SaveToFileSimple(FileName:String);
    Procedure SaveToFileOptimize(FileName:String);
    Procedure LoadFromFile(FileName:String);
  published
    { Déclarations publiées }
    Property Byte0:Byte Read FByte1 write FByte1;
    Property Byte1:Byte Read FByte2 write FByte2;
    Property Byte2:Byte Read FByte3 write FByte3;
    Property Byte3:Byte Read FByte4 write FByte4;
  end;
0
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
4 août 2014 à 15:04
ShortString est obsolète dans ton cas de figure mais pas dans le sens ou tu l'as compris : Il est inutile car une IP n'est pas constituée de 255 caractères, de ce fait en pensant faire de l'optimisation tu n'en fais pas. Le type String est donc plus approprié : Voila le sens de ma réponse initiale.
0
MiniApp Messages postés 654 Date d'inscription lundi 21 juillet 2014 Statut Membre Dernière intervention 22 février 2019 5
4 août 2014 à 15:05
Réglez. Mais ça bug toujours
0
MiniApp Messages postés 654 Date d'inscription lundi 21 juillet 2014 Statut Membre Dernière intervention 22 février 2019 5
Modifié par MiniApp le 5/08/2014 à 14:51
J'ai résolu mon problème,

J'ai regarder l'aide de TStringList et j'ai vu que TStringsList avait son propre Add, alors j'ai remplacer mon TStrings par TStringsList ce qui a marcher. Le problème ensuite c'est que le test pour savoir quelle chaines est la plus courtes était érronée, alors j'ai fait une variables temp qui est un String et que j'utilise pour trouver la chaine la plus courtes que je rentre dans TStringList.
Le code final :
Procedure TIPv4.SaveToFileOptimize(FileName:String);
{Enregistre dans le format le plus court
Format (127.0.0.1) :
[SM]Simple(127.0.0.1)->127.0.0.1:Codage standard sans simplification
[S0]Supp0(127.0.0.1)->127...1:Supression des 0
[NP]NoPoint(255.255.255.255)->255255255255:Supprime les points (uniquement si chaque Octect > 99)
[NM]Name(127.0.0.1)->me:Transforme en nom si possible}
Var
Temp:String;
Strings:TStringList;
Supp0:String;
NoPoint:String;
Name:String;
Begin
//Préparation
Strings := TStringList.Create;//Initialisation de Strings
//Application des algorithme
  //Supp0
  If FByte1 = 0 Then//Simplique du 1er octect possible?
    Supp0 := '.'
  Else Supp0 := IntToStr(FByte1)+'.';
  If FByte2 = 0 Then//Simplique du 2e octect possible?
    Supp0 := Supp0 + '.'
  Else Supp0 := Supp0 + IntToStr(FByte2)+'.';
  If FByte3 = 0 Then//Simplique du 3e octect possible?
    Supp0 := Supp0 + '.'
  Else Supp0 := Supp0 + IntToStr(FByte3)+'.';
  If FByte4 = 0 Then//Simplique du 4e octect possible?
  Else Supp0 := Supp0 + IntToStr(FByte4);
  //NoPoint
  If (FByte1 > 99) and (FByte2 > 99) and (FByte3 > 99) and (FByte4 > 99) Then
    NoPoint := GetIP('')
  Else NoPoint := GetIP;
  //Name
  Name := '255.255.255.2550';
  If GetIP = '127.0.0.1' Then
    Name := 'me';
  If GetIP = '255.255.255.255' Then
    Name := '+';
  If GetIP = '0.0.0.0' Then
    Name := '-';
  If GetIP = '192.168.1.1' Then
    Name := 'nat1';
  If GetIP = '192.168.0.1' Then
    Name := 'nat0';
//Recherche de l'algorithme le plus court
Temp := 'SM' + GetIP;//Simple
 If Length(Supp0) < Length(Temp) Then//Supp0
   Begin
     Temp := 'S0' + Supp0;
   end;
 If Length(NoPoint) < Length(Temp) Then//NoPoint
   Begin
     Temp := 'NP' + NoPoint;
   end;
 If Length(Name) < Length(Temp) Then//Name
   Begin
     Temp := 'NM' + Name;
   end;
//Enregistrement
Strings.Text := Temp;
Strings.SaveToFile(FileName);
end;


L'encodeur marche.

Chercher et essayer : vous trouverez la solution!
Fouiner et regarder partout : vous trouverez la connaissance!!
0
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
Modifié par Francky23012301 le 5/08/2014 à 17:06
Sauf que tu ne libères toujours pas ton Strings et que l'utilisation d'un try except est plus que conseillé.

CptPingu : Si MiniApp veut juste un logiciel pour pinger effectivement autant l'orienter vers un truc existant, après si son objectif est de le faire lui même autant ne pas lui priver de ce plaisir :).

Cirec : Il est possible que le nombre de threads lancé par cette application dépend du nombre d'ip à scanner, d'ou la fausse anomalie que tu indiques :). Par contre pourrais tu juste faire les même essais que CptPingu au niveau du nombre d'ip pinger en utilisant non 50 threads mais 200 juste pour voir ce que cela donne : Je suis assez curieux du résultat ;).
0
MiniApp Messages postés 654 Date d'inscription lundi 21 juillet 2014 Statut Membre Dernière intervention 22 février 2019 5
Modifié par MiniApp le 5/08/2014 à 18:02
Merci pour le TStringList, je vais mettre un try finally
0
Cirec Messages postés 3833 Date d'inscription vendredi 23 juillet 2004 Statut Modérateur Dernière intervention 18 septembre 2022 50
Modifié par Cirec le 5/08/2014 à 18:01
ben en fait j'avais aussi testé cette partie et peu importe le type de processeur
le code limité à 256 Threads est ~1sec plus long qu'avec 50 Threads

et dans les deux cas (XP et Seven) l'os ne laisse pas créer autant de Threads(256) simultanément
le système semble les retenir les mettre en attente !!! (~160 - 170 Max)

justement c'est pour cela que ça m'étonne un peu ... en plus chaque réponse prend ~40ms ce sont donc des limites physiques que l'on approche tout doucement ... après cet outil n'utilise certainement pas la méthode que la notre ... la quelle il faut le rappeler avait pour but de départ de faire 1 Ping sans utiliser Indy ou autre composant tiers ... on est donc parti sur une commande Dos, un simple Ping !

... je reste donc dubitatif ^^

    
@+ Cirec
0
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
Modifié par Francky23012301 le 5/08/2014 à 18:58
On peut se passer du dos (shell) et je me demande même si en terme de perfs si cela ne serait pas mieux du reste et j'en serai pas étonné.

Merci pour le retour de tests : Justement j'attendais la conclusion que tu nous a donné soit une limitation du nombre de threads actifs par l'Os (Voir les mots précédents de MiniApp sur la possibilité d'utiliser un nombre conséquents de threads).
0
MiniApp Messages postés 654 Date d'inscription lundi 21 juillet 2014 Statut Membre Dernière intervention 22 février 2019 5
7 août 2014 à 18:18
Pour ajuster la consomation de l'application j'ai trouver ceci. Et j'ai même réussi à le compiler dans mon Delphi 5 ! Une modification du code-source peut faire un smart programme.
0
Francky23012301 Messages postés 400 Date d'inscription samedi 6 août 2005 Statut Membre Dernière intervention 11 février 2016 1
8 août 2014 à 03:53
Ca ne permet pas d'ajuster mais simplement d'évaluer les ressources utilisées par ton source : Ceci dit il existe des applications externes qui te permettent la même chose, ce qui est nettement plus pratique, et de façon plus détaillée.
0
MiniApp Messages postés 654 Date d'inscription lundi 21 juillet 2014 Statut Membre Dernière intervention 22 février 2019 5
8 août 2014 à 10:07
Je parlait de l'intégrer à un programme.
0
Rejoignez-nous