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#

  1. #1
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 1 986
    Points : 2 208
    Points
    2 208
    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 éminent sénior

    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 : 40
    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
    Points : 10 543
    Points
    10 543
    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 chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 1 986
    Points : 2 208
    Points
    2 208
    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 éminent sénior

    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 : 40
    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
    Points : 10 543
    Points
    10 543
    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 régulier
    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
    Points : 109
    Points
    109
    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 chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 1 986
    Points : 2 208
    Points
    2 208
    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

  7. #7
    Expert éminent sénior

    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 : 40
    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
    Points : 10 543
    Points
    10 543
    Billets dans le blog
    21
    Par défaut
    Il n'y a rien qui m'interpelle dans ton code.

    Lorsque tu envoies un code erroné, le serveur le reçoit 3x, mais côté client, combien as-tu d'erreur qui apparaissent ?

    As-tu essayé de déboguer en pas à pas ton backgroundworker afin d'étudier son fonctionnement ?

  8. #8
    Membre chevronné Avatar de petitours
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Février 2003
    Messages
    1 986
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44
    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 : 1 986
    Points : 2 208
    Points
    2 208
    Par défaut
    Citation Envoyé par dorinf Voir le message
    Il n'y a rien qui m'interpelle dans ton code.
    Là je suis fier...

    Citation Envoyé par dorinf Voir le message
    Lorsque tu envoies un code erroné, le serveur le reçoit 3x, mais côté client, combien as-tu d'erreur qui apparaissent ?
    Le client déclenche une seule fois, il n'y a qu'une seule erreur qui apparait, une fois les 3 retry terminés.

    Citation Envoyé par dorinf Voir le message
    As-tu essayé de déboguer en pas à pas ton backgroundworker afin d'étudier son fonctionnement ?
    et là je me sens .on, d'une parce que je crois pas l'avoir fait et de deux parce que ce matin je n'arrive pas à avoir le problème !! (alors que je n'ai pas touché ni le client, ni le serveur depuis que j'ai posté ma question)
    Je m'acharne et je reviens...

    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