C# Paquet trop long

Inscrit
19 Mai 2013
Messages
68
Reactions
0
#1
Salut à tous !

Je rencontre actuellement un problème lors de la lecture de la longueur des paquets. Mon code est celui de -débuter-dans-le-développement-socket-d2-(complet).162/]RaphyTheGeek, soit pour les flemmards :

Code:
private void ParseData(byte[] DataToParse)
        {
            // Déclaration des variables qui seront utilisées
            int index = 0;
            short id_and_packet_lenght_type, packet_id, packet_lenght_type;
            Int32 packet_lenght = 0;
            byte[] packet_content;

            // Lecture jusqu'à la fin de byte[] data
            while (index != DataToParse.Length)
            {
                // Décodage du header
                id_and_packet_lenght_type = (short)(DataToParse[index] * 256 + DataToParse[index + 1]); // Selection des 2 premiers octets du paquet
                packet_id = (short)(id_and_packet_lenght_type >> 2); // Récupérer l'ID du paquet
                packet_lenght_type = (short)(id_and_packet_lenght_type & 3); // Récupérer la taille de la taille de la longueur du paquet

                index += 2; // On se déplace 2 octets plus loin

                // Récupération de la taille du paquet
                switch (packet_lenght_type)
                {
                    case 0:
                        packet_lenght = 0;
                        break;
                    case 1:
                        packet_lenght = DataToParse[index];
                        break;
                    case 2:
                        packet_lenght = DataToParse[index] * 256 + DataToParse[index + 1];
                        break;
                    case 3:
                        packet_lenght = DataToParse[index] * 65536 + DataToParse[index + 1] * 256 + DataToParse[index + 2];
                        break;
                }

                // Récupération du contenu du paquet
                packet_content = new byte[(int)packet_lenght];
                Array.Copy(DataToParse, index + packet_lenght_type, packet_content, 0, packet_lenght);

                // Création de la variable contenant le contenu du paquet en héxadécimal
                string content_hex = string.Empty;
                int huit_bytes = 0;
                foreach (byte b in packet_content)
                {
                    if (huit_bytes == 8)
                    {
                        content_hex += "\r\n";
                        huit_bytes = 0;
                    }
                    content_hex += b.ToString("X2") + " ";
                    huit_bytes++;

                }

                // Jounalisation
                Log("[Reçu] ID = " + packet_id + " | Taille du contenu = " + packet_lenght + "\r\n" + content_hex);

                // Traitement du paquet
                TreatPacket(packet_id, packet_content);

                // Définition de l'index qui démarre le paquet suivant
                index += packet_lenght + packet_lenght_type;
            }
        }
Je rencontre un problème sur le paquet PrismsListMessage (ID = 6440). Le problème apparaît lors du Array.Copy, étant donné que la longueur du packet est plus longue que la longueur de DataToParse. En effet, j'obtiens un packet_lenght_type de 2, et une longueur de 11911 (au lieu d'environ 3500). J'ai par ailleurs remarqué que la variable index était, à l'endroit du bug, d'environ 120 au lieu de 2 (étant donné le packet_lenght_type de 2).

Si quelqu'un a la solution, ou si quelqu'un a déjà rencontré ce problème, il est le bienvenu ! :)
En espérant vous avoir donné suffisamment d'infos ! :)

Veriditas !
 
Inscrit
19 Mai 2013
Messages
68
Reactions
0
#2
Je remarque aussi que parfois, j'obtiens des ID de paquet négatifs. Ici par exemple, j'ai planté en recevant le paquet d'ID -20, avec un Lenght Type de 2, un Lenght de 65465 et un index de 1201.
 

asyade

Membre Actif
Inscrit
26 Avril 2013
Messages
368
Reactions
1
#3
il me semble que le parsing et un peut dépasser (beaucoup) regarde du coter de euubot ,leafbot ou bim
 
Inscrit
19 Mai 2013
Messages
68
Reactions
0
#4
D'accord. (J'ai cherché dans BiM, mais j'ai pas trouvé la méthode où il faisait ça, je vais aller voir chez EuuBot)

EDIT : J'ai eu cette erreur, cette fois avec le paquet NotificationListMessage (ID = 6087), avec un paquet de 11 bytes, un Lenght Type de 1, et un Lenght de 6. Cette fois, le Lenght est inférieur au paquet original, et j'ai quand même l'erreur, mais c'est certainement parce que la variable index est à 9 au lieu de 2 ou 3.
 
Inscrit
19 Mai 2013
Messages
68
Reactions
0
#5
Je me suis penché sur la méthode EuuBot, et j'en suis arrivé à ça. Ca marche pas très bien du tout, est-ce que vous avez des trucs à corriger à me proposer :

Code:
        private void ParseBuffer(byte[] buffer_To_Parse)
        {
            short header;
            short packet_ID;
            short type_Length;
            short packet_Length;
            int index = 0;

            while (buffer_To_Parse.Length > index + 2)
            {
                header = (short)buffer_To_Parse[index];
                header <<= 8;
                index++;
                header += (short)buffer_To_Parse[index];

                packet_ID = (short)(header >> 2);

                type_Length = (short)(header & 3);

                switch (type_Length)
                {
                    case 0:
                        packet_Length = 0;
                        break;

                    case 1:
                        index++;
                        packet_Length = (short)buffer_To_Parse[index];
                        break;

                    case 2:
                        index++;
                        packet_Length = (short)buffer_To_Parse[index];
                        packet_Length <<= 8;
                        index++;
                        packet_Length += (short)buffer_To_Parse[index];
                        break;

                    case 3:
                        index++;
                        packet_Length = (short)buffer_To_Parse[index];
                        packet_Length <<= 8;
                        index++;
                        packet_Length += (short)buffer_To_Parse[index];
                        packet_Length <<= 8;
                        index++;
                        packet_Length += (short)buffer_To_Parse[index];
                        break;

                    default:
                        throw new Exception("headerTypeLen can be of a maximum of 3");
                }

                if (buffer_To_Parse.Length >= (type_Length + 2 + packet_Length))
                {
                    byte[] packet_Content;

                    packet_Content = new byte[packet_Length];
                    Array.Copy(buffer_To_Parse, index + 1, packet_Content, 0, packet_Length);

                    TreatPacket(packet_ID, packet_Content);

                    index += packet_Length;
                }
                else
                {
                    return;
                }
            }
        }
 

bouh2

Membre Actif
Inscrit
12 Septembre 2008
Messages
184
Reactions
21
#6
Regarde la classe MessagePart sur BiM
 
Inscrit
19 Mai 2013
Messages
68
Reactions
0
#8
C'est bon tout fonctionne !

Code:
        private void ParseBuffer(byte[] buffer_To_Parse)
        {
            int header;
            int message_ID;
            int length_Count;
            int length;
            byte[] packet_Content = new byte[0];

            using (BigEndianReader big_Endian_Reader = new BigEndianReader(buffer_To_Parse))
            {
                while (big_Endian_Reader.bytes_Avaibles >= 2)
                {
                    header = big_Endian_Reader.ReadShort();

                    message_ID = header >> 2;
                    length_Count = header & 0x3;

                    if (big_Endian_Reader.bytes_Avaibles >= length_Count)
                    {
                        if ((length_Count < 0) || (length_Count > 3))
                        {
                            throw new Exception("Malformated Message Header, invalid bytes number to read message length (inferior to 0 or superior to 3)");
                        }
                        else
                        {
                            length = 0;

                            for (int i = length_Count - 1; i >= 0; i--)
                            {
                                length |= big_Endian_Reader.ReadByte() << (i * 8);
                            }

                            if (length == 0)
                            {
                                packet_Content = new byte[0];
                            }

                            if (big_Endian_Reader.bytes_Avaibles >= length)
                            {
                                packet_Content = big_Endian_Reader.ReadBytes(length);
                            }
                            else if (big_Endian_Reader.bytes_Avaibles < length)
                            {
                                packet_Content = big_Endian_Reader.ReadBytes((int)big_Endian_Reader.bytes_Avaibles);
                            }

                            MainForm.actual_MainForm.SetText("Paquet reçu, ID : " + message_ID.ToString());


                            TreatPacket(message_ID, packet_Content);
                        }
                    }
                }
            }
        }
Merci à toi bouh² ! :)
 

ToOnS

Membre Actif
Inscrit
8 Avril 2009
Messages
974
Reactions
0
#9
asyade a dit:
il me semble que le parsing et un peut dépasser (beaucoup) regarde du coter de euubot ,leafbot ou bim
depuis le 1er jour son parser marche pas , je lui ai dit pourtant , c'est juste parceque sur les longs messages c'est sur 2 paquets (ou plus) donc si la taille du message depasse la taille de ce qui reste du paquet en cours de traitement il faut ajouter le paquet suivant a la suite du paquet en cours de traitement
 

Sparkdaemon

Staff
Membre du personnel
Inscrit
7 Avril 2009
Messages
556
Reactions
3
#10
Merci d'éditer tes posts au lieu de faire des doubles-post a chaque fois
 
Inscrit
19 Mai 2013
Messages
68
Reactions
0
#11
ToOnS a dit:
asyade a dit:
il me semble que le parsing et un peut dépasser (beaucoup) regarde du coter de euubot ,leafbot ou bim
depuis le 1er jour son parser marche pas , je lui ai dit pourtant , c'est juste parceque sur les longs messages c'est sur 2 paquets (ou plus) donc si la taille du message depasse la taille de ce qui reste du paquet en cours de traitement il faut ajouter le paquet suivant a la suite du paquet en cours de traitement
Donc ce que j'ai fait n'est toujours pas bon ?

Sparkdaemon a dit:
Merci d'éditer tes posts au lieu de faire des doubles-post a chaque fois
Pardon, ça ne se reproduira plus !
 

asyade

Membre Actif
Inscrit
26 Avril 2013
Messages
368
Reactions
1
#12
si si c'est bon, c'est juste que le premier parsing que tu a utilisée na jamais marcher ^^'
 
Haut Bas