IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

C# Discussion :

Client TCP qui fait des retry sans savoir pourquoi


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut Client TCP qui fait des retry sans savoir pourquoi
    Bonjour

    Je me suis fait un serveur TCP qui envoi des informations à une autre machine, ca fonctionne mais je me suis étonné que le délai de timeout ne soit pas respecté (10s en tout)

    voici mon code ou je configure un timout en écriture et en lecture de 1000 (1seconde)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    try
                {
                    bgWOrdreSimple_Parametres args = (bgWOrdreSimple_Parametres)e.Argument;
     
                    using (TcpClient client = new TcpClient(args.IP, args.port)) // ouverture du socket
                    {
                        using (NetworkStream stream = client.GetStream())//récupération du stream du socket
                        {
                            args.data[0] = 255; // c'est un ordre on a donc 255
     
                            stream.WriteTimeout = args.WriteTimeOut ;  //réglage des timeout                        
                            stream.ReadTimeout = args.ReadTimeOut ;
     
                            int ResteAEnvoyer = args.data.Length;
                            int PositionDansBuffer = 0 ;
                            int Aenvoyer = 0;
                            while (ResteAEnvoyer > 0)
                            {
                                Aenvoyer = ResteAEnvoyer;
     
                                if (ResteAEnvoyer > 250)
                                        Aenvoyer = 250; //on envoi maximum 250o à la fois
     
                                stream.Write(args.data, PositionDansBuffer, Aenvoyer);
                                PositionDansBuffer += Aenvoyer;
                                ResteAEnvoyer -= Aenvoyer;
                            }
     
                            if (Aenvoyer == 250) // si la dernière trame faisait pile 250o on envoit un saut de ligne en plus (IndusBee se sert de 250 pour savoir s'il doit attendre la suite d'une trame
                            {
                                byte[] trameCourte = System.Text.Encoding.ASCII.GetBytes("\r\n");
                                stream.Write(trameCourte, 0, trameCourte.Length);
                            }
     
                            // Buffer to store the response bytes.
                            byte[] LaReponse = new Byte[512];
     
                            // attente réponse le temps du timeout
                            Int32 bytes = stream.Read(LaReponse, 0, LaReponse.Length);
     
                            responseString = System.Text.Encoding.ASCII.GetString(LaReponse, 0, bytes);
                        }
                    }               
                }
    Je viens de me rendre compte via la console du serveur que ce code fait 2 retry (3 tentatives en tout) avant de me lever le timeout (d'où la durée largement supérieure à 1s).

    Je n'arrive pas à trouver de paramètres qui règlent ces retry, que j'aimerais supprimer pour que mes timeout soient respectés.

    Merci par avance pour votre aide

  2. #2
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Bonjour,

    Sans plus d'informations, difficile de t'aider. Il n'y a pas de notion de Retry au niveau des TcpSocket (et donc des NetworkStream).

    Peux-tu nous donner les éléments suivants :
    • Le code côté serveur ;
    • Le code côté client ;
    • Où se produit le timeout ? Est-ce sur une lecture ? Une écriture ? Et de quel côté ? Client ou serveur ?
    • Une explication précise du comment tu as diagnostiqué le Retry (tu as mis un Console.WriteLine quelque part par exemple ?)

  3. #3
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Bonjour

    Le code coté client est dans mon premier message
    Celui coté serveur est sur une carte électronique, c'est du C, je dois pouvoir le trouver mais pas facilement...

    J’envoie un ordre pour lancer une action (3 octets en TCP) et j'attends une réponse de la carte électronique
    Pour tester le timeout j’envoie un ordre faux auquel la carte ne répond pas.

    Si j'envoie cet ordre avec un client TCP quelconque (j'en ai essayé 3) la carte électronique ne me répond rien et le client échoue sur timout. Je sais que la carte a bien reçu l'ordre erroné parce qu’il apparait sur une console.
    avec Mon client (code ci dessus) la carte ne répond pas de la même manière mais je vois sur la console qu'il y a 3 x l'ordre qui arrive avant que le timout déclenche.
    Si j’envoie un ordre valide la carte électronique reçoit bien qu'une seule fois l'ordre.

    Merci

  4. #4
    Expert confirmé

    Avatar de François DORIN
    Homme Profil pro
    Consultant informatique
    Inscrit en
    Juillet 2016
    Messages
    2 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Charente Maritime (Poitou Charente)

    Informations professionnelles :
    Activité : Consultant informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2016
    Messages : 2 761
    Billets dans le blog
    21
    Par défaut
    Le code du client n'est pas complet. Qu'y a-t-il avant le try ? Ou est le catch ?

  5. #5
    Membre très actif
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Juillet 2015
    Messages
    128
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Juillet 2015
    Messages : 128
    Par défaut
    c'est impossible que seulement ce code il va t’excuser plus qu'une foit, le probleme est dans la partie qui appelle cette function, (si tu l'a comme function)

  6. #6
    Membre extrêmement actif Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    2 037
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : Industrie

    Informations forums :
    Inscription : Février 2003
    Messages : 2 037
    Par défaut
    Bonjour

    Voici la totalité du code client qui envoi l'ordre

    ca commence par un clic sur un bouton...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    private void BtOrdre_ForcerRecupDatas_Click(object sender, EventArgs e)
            {
                bgWOrdreSimple_Parametres monParam = new bgWOrdreSimple_Parametres();
                monParam.IP = textBoxIPaJoindre.Text;
                monParam.port = (int)numericUpDownPortAJoindre.Value;
                monParam.SSL = checkBox_SLLordresTCP.Checked;
                monParam.ReadTimeOut = 1000;
                monParam.WriteTimeOut = 1000;
                monParam.data = new byte[2]; //[0] prendra la valeur 255 dans tous les cas
                monParam.data[1] = 5; //ordre
     
                richTextBox_LogDesOrdres.SelectionColor = Color.DarkGreen;
                richTextBox_LogDesOrdres.AppendText(DateTime.Now.ToString() + "- Ordre forcer transfert fichiers DATA à " + textBoxIPaJoindre.Text + ":" + numericUpDownPortAJoindre.Value.ToString() + "\r\n");
     
                EnvoiOrdreTCP(monParam);
            }
    ou je prépare un paramètre que je vais passer à un backgroundworker

    puis la fonction EnvoiTCP

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    private void EnvoiOrdreTCP(bgWOrdreSimple_Parametres monParam)
            {
                if (bgWorkerOrdreSimple.IsBusy != true)
                {
                    bgWorkerOrdreSimple.RunWorkerAsync(monParam);
                }
                else
                {
                    richTextBox_LogDesOrdres.SelectionColor = Color.Red;
                    richTextBox_LogDesOrdres.AppendText("Client TCP occupé : aucun ordre envoyé.\r\n\r\n");
                }
            }
    et le backgroundworker qui fait l'envoi et attend une réponse
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
     
    private void bgWorkerOrdreSimple_DoWork(object sender, DoWorkEventArgs e)
            {
                String responseString = String.Empty;
     
                try
                {
                    bgWOrdreSimple_Parametres args = (bgWOrdreSimple_Parametres)e.Argument;
     
                    using (TcpClient client = new TcpClient(args.IP, args.port)) // ouverture du socket
                    {
                        using (NetworkStream stream = client.GetStream())//récupération du stream du socket
                        {
                            args.data[0] = 255; // c'est un ordre on a donc 255
     
                            stream.WriteTimeout = args.WriteTimeOut ;  //réglage des timeout                        
                            stream.ReadTimeout = args.ReadTimeOut ;
     
                            int ResteAEnvoyer = args.data.Length;
                            int PositionDansBuffer = 0 ;
                            int Aenvoyer = 0;
                            while (ResteAEnvoyer > 0)
                            {
                                Aenvoyer = ResteAEnvoyer;
     
                                if (ResteAEnvoyer > 250)
                                        Aenvoyer = 250; //on envoi maximum 250o à la fois
     
                                stream.Write(args.data, PositionDansBuffer, Aenvoyer);
                                PositionDansBuffer += Aenvoyer;
                                ResteAEnvoyer -= Aenvoyer;
                            }
     
                            if (Aenvoyer == 250) // si la dernière trame faisait pile 250o on envoit un saut de ligne en plus (IndusBee se sert de 250 pour savoir s'il doit attendre la suite d'une trame
                            {
                                byte[] trameCourte = System.Text.Encoding.ASCII.GetBytes("\r\n");
                                stream.Write(trameCourte, 0, trameCourte.Length);
                            }
     
                            // Buffer to store the response bytes.
                            byte[] LaReponse = new Byte[512];
     
                            // attente réponse le temps du timeout
                            Int32 bytes = stream.Read(LaReponse, 0, LaReponse.Length);
     
                            responseString = System.Text.Encoding.ASCII.GetString(LaReponse, 0, bytes);
                        }
                    }               
                }
                catch (ArgumentNullException Ex)
                {
                    richTextBox_LogDesOrdres.SelectionColor = Color.Red;
                    richTextBox_LogDesOrdres.AppendText("Error : " + Ex.Message + "\r\n\r\n");
                }
     
                e.Result = responseString;
            }
     
     
            private void bgWorkerOrdreSimple_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
            {
                if (!(e.Error == null))
                {
                    richTextBox_LogDesOrdres.SelectionColor = Color.Red;
                    richTextBox_LogDesOrdres.AppendText("Error: " + e.Error.Message + "\r\n\r\n");
                }
     
                else
                {
                    richTextBox_LogDesOrdres.SelectionColor = Color.DarkGreen;
                    richTextBox_LogDesOrdres.AppendText("Done! : " + e.Result  + "\r\n\r\n");
                }
            }
    Si j’envoie un ordre invalide la carte ne répond pas mais je vois sur sa console 3 envoi successifs avant de voir le backgroundworker enfin terminer (ca fait long)
    J'ai essayé cet envoi avec d'autres clients et il ya qu'une tentative, la carte se contente de pas répondre à l'ordre invalide reçu.

    Je n'ai pas trouvé la moindre piste pour expliquer ce retry !

    Merci

Discussions similaires

  1. Réponses: 21
    Dernier message: 05/12/2007, 16h32
  2. [XHTML] XHTML -> IE qui fait des siennes!
    Par onet dans le forum Balisage (X)HTML et validation W3C
    Réponses: 7
    Dernier message: 20/03/2007, 21h50
  3. Menu qui fait des misères
    Par kaiser59 dans le forum Mise en page CSS
    Réponses: 5
    Dernier message: 08/12/2006, 20h06
  4. Pop up qui fait des siennes !
    Par Sandara dans le forum Général JavaScript
    Réponses: 14
    Dernier message: 13/06/2006, 16h40
  5. [Tool Tip Text]Lien qui affiche des infos sans cliquer !
    Par Melchisedec dans le forum Général Conception Web
    Réponses: 2
    Dernier message: 08/06/2006, 14h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo