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 :

Problème de réception de trame via dialogue IP [Débutant]


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 29
    Par défaut Problème de réception de trame via dialogue IP
    Bonjour,

    Je dialogue avec une carte Electronique en Ethernet. J'envoi une commande ST (de statut), mais je dois cliquer plusieurs fois sur envoyer pour recevoir l'intégralité de ma trame.

    J'ai donc fait ce petit test: attendre que je reçoive ! ou ? pour return le message reçu...

    Sauf que cela fait une boucle infinie... ce caractère "!" correspond à une commande comprise par le panneau (Ack), à l'inverse Nack, cependant quand j'envoi une commande il ce peu que je reçoive "!" dans un premier Click ou un début de réponse STAT mais pas tout, il faut que je reclick pour avoir l'intégralité de la réponse de l'UC!

    Voici le code:
    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
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using System.Windows.Forms;
    using System.Diagnostics;
    using System.IO;
    using System.Net.Sockets;
    using System.Net;
     
    namespace Liaison_IP
    {
     
     
        public partial class Form1 : Form
        {
            System.Net.Sockets.TcpClient clientSocket = new System.Net.Sockets.TcpClient();
     
     
            public Form1()
            {
                InitializeComponent();
     
            }
     
            private void BP_Connect_Click(object sender, EventArgs e)
            {
                try
                {
                    clientSocket.Connect("X.X.X.X", 2101);
                    lb_Etatduport.Text="Port ouvert";
                }
                catch
                {
                    MessageBox.Show("erreur de connexion", "erreur");
                }
            }
     
            public void BP_Envoyer_Click(object sender, EventArgs e)
            {
                NetworkStream serveurStream = clientSocket.GetStream();
                byte[] outStream = System.Text.Encoding.ASCII.GetBytes(TB_MessageEnvoye.Text+'\r');
                try
                {
     
                    serveurStream.Write(outStream, 0, outStream.Length);
                    serveurStream.Flush();
     
                    byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
                    int nbrlu=serveurStream.Read(inStream, 0, clientSocket.ReceiveBufferSize);
                    string returndata = System.Text.Encoding.ASCII.GetString(inStream, 0, nbrlu);
     
                    foreach (byte b in inStream)
                    {
                        if (b.ToString().Equals("!") || b.ToString().Equals("?"))
                        {
                            messagerecu(returndata);
                            TB_MessageEnvoye.Text = "";
                            TB_MessageEnvoye.Focus();
                        }
                    }
     
                }
                catch 
                {
                    MessageBox.Show("erreur d'envoi", "erreur");
                }
            }
     
                public void messagerecu(string msg)
                {
                    TB_MessageReçu.Text=TB_MessageReçu.Text + msg;
     
                }
     
            private void Initializetimertestpicto()
            {
                timertestpicto.Enabled=true;
                timertestpicto.Interval=60000;
            }
     
     
     
        }
    }
    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
    public void BP_Envoyer_Click(object sender, EventArgs e)
            {
                NetworkStream serveurStream = clientSocket.GetStream();
                byte[] outStream = System.Text.Encoding.ASCII.GetBytes(TB_MessageEnvoye.Text+'\r');
                try
                {
     
                    serveurStream.Write(outStream, 0, outStream.Length);
                    serveurStream.Flush();
     
                    byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
                    int nbrlu=serveurStream.Read(inStream, 0, clientSocket.ReceiveBufferSize);
                    string returndata = System.Text.Encoding.ASCII.GetString(inStream, 0, nbrlu);
     
                    /*foreach (byte b in inStream)
                    {
                        if (b.ToString().Equals("!") || b.ToString().Equals("?"))
                        {
                            messagerecu(returndata);
                            TB_MessageEnvoye.Text = "";
                            TB_MessageEnvoye.Focus();
                        }
                    }*/
                    messagerecu(returndata);
                    TB_MessageEnvoye.Text = "";
                    TB_MessageEnvoye.Focus();
                }
    Quand je compile avec ce code:

    J'envoi par un click: ST et je reçois: STAT il faut que je reclick sur le bouton envoyer pour avoir: STATUS ADR=010 BTR=0 CKS=0FAD COD=I0106.0 CTL=0 EDF=0 ER0=00 ER1=00 ER2=00 ERI=I0052/4.0.15/0 EVT=ERI:20/03/15 09:08:16 GAR=000 GAT=0 GEN=LAX.PA1 INI=015 LOC=CARROS MOV=0 NST=2004 RST=023 TRM=0 VER=001!

    Merci, amis experts csharp de m'aiguiller sur le sujet!

    Cordialement,

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    c'est plus une question de connaissance sur le protocole tcp/ip


    celui ci envoi les données par paquets
    déjà si le truc de l'autre côté renvoie un acquittement puis réfléchit quelques microsecondes avant d'envoyer les infos, il t'aura fait 2 envoies, et toi tu ne lis qu'une fois ce qu'il y a dans le buffer
    avec un autre clic tu lis simplement la suite du buffer qui t'attendais déjà
    s'il prend du temps à répondre un acquittement tu n'auras même rien à lire avec ton code
    de plus un paquet peut tout à fait être coupé en plusieurs morceaux, surtout si l'envoi est gros
    dans le principe, le logiciel remplit le buffer, le buffer est envoyé, le logiciel met la suite, qui est envoyée etc... et le buffer ne fait que quelques kilos
    mais même si tu veux envoyer 2 octets (= 2 caractères en ascii) et que le matériel a des soucis de collisions à ce moment là et que dans le buffer il ne reste qu'un octet de libre, tes 2 caractères seront envoyés en 2 fois


    aussi il convient de "lire" en continue ou mieux d'utiliser les méthodes asynchrones qui te préviennent quand il y a quelque chose à lire
    et de concaténer tout ce que tu reçois puis découper une trame en fonction soit d'une longueur, soit d'un caractère de fin de trame (ou autre)
    et après seulement traiter la trame

    mais écrire puis lire tout de suite ce n'est pas la chose à faire

    ou si tu veux faire un truc tout moche, tu attends une bonne seconde après avoir écrit avant de lire
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 29
    Par défaut
    D'accord, merci pour ta réponse! Je vais revoir mon code, je reviendrais surement vers toi

  4. #4
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 29
    Par défaut
    je ne sais pas qu'elle méthode utiliser... les threads? c'est compliquer je ne comprend pas comment mettre ça en place. ou faut il utiliser async et await? Lire en continue? c'est à dire byte/byte ?

  5. #5
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 43
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 198
    Par défaut
    le plus simple c'est les méthodes asynchrone
    genre .beginread
    à celle ci tu donnes une adresse de retour (un callback)
    quand il y a quelque chose à lire, la méthode est appelée, et dans ce void tu lis les données, que tu enregistres quelque part (genre concaténer dans une variable de classe)
    et à la fin de la lecture, il faut rappeler .beginread avec le même callbak, comme ca s'il y a à nouveau quelque chose à lire ca repassera ici et concaténera de nouveau

    et après concaténation, tu regardes ce que la variable contient, si tu vois une trame entière, tu la supprimes de cette concaténation et tu la traites
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  6. #6
    Membre averti
    Homme Profil pro
    Technicien maintenance
    Inscrit en
    Février 2015
    Messages
    29
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Technicien maintenance

    Informations forums :
    Inscription : Février 2015
    Messages : 29
    Par défaut
    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
     
                NetworkStream serveurStream = clientSocket.GetStream();
                byte[] outStream = System.Text.Encoding.ASCII.GetBytes(TB_MessageEnvoye.Text+'\r');
                try
                {
     
                    serveurStream.Write(outStream, 0, outStream.Length);
                    serveurStream.Flush();
     
                    byte[] inStream = new byte[clientSocket.ReceiveBufferSize];
                    AsyncCallback callback;
                    Object state;
                    serveurStream.BeginRead(inStream, 0, clientSocket.ReceiveBufferSize, callback, state);
     
     
                    string returndata = System.Text.Encoding.ASCII.GetString(inStream, 0, );
                    messagerecu(returndata);
    j'ai un peu de mal... :s

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Problème de réception de données via QTcpSocket
    Par bilou_2007 dans le forum Débuter
    Réponses: 12
    Dernier message: 16/04/2011, 20h45
  2. Problème de réception via TCP
    Par Guispeed4262 dans le forum Réseau
    Réponses: 7
    Dernier message: 29/12/2010, 11h38
  3. Affichage incomplet après réception d'une trame via RS232
    Par sroge dans le forum Composants VCL
    Réponses: 3
    Dernier message: 01/02/2008, 15h50
  4. [Configuration] problème de réception de mail via formulaire
    Par FraK dans le forum EDI, CMS, Outils, Scripts et API
    Réponses: 5
    Dernier message: 26/06/2007, 17h45
  5. Réponses: 3
    Dernier message: 29/08/2003, 10h57

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