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 :

Reception de message TCP difficile en mode Asynchrone


Sujet :

C#

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 74
    Par défaut Reception de message TCP difficile en mode Asynchrone
    Bonjour, j'ai un probleme avec un application TCP que j'essaie de faire.

    Elle envoie un message à un serveur, qui lui retourne des enregistrement de valeurs (séparés par des virgules). Le problème est que je ne peux prévoir la grandeur de ces enregistrement (souvent plus que 1000 enregistrements) donc je ne peux fixer mon buffer, ce qui m'oblige à faire plusieurs lecture.

    Voici le code tiré de la classe TcpSocket qui communique avec le serveur TCP

    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
    privatevoid WaitForData()
    {
    if (pfnCallBack == null)
    pfnCallBack = newAsyncCallback(OnDataReceived);
    // now start to listen for any data...
    m_asynResult = client.BeginReceive(m_DataBuffer, 0, m_DataBuffer.Length, SocketFlags.None, pfnCallBack, null);
    }
    publicvoid OnDataReceived(IAsyncResult asyn)
    {
    //end receive...
    int iRx = 0;
    iRx = client.EndReceive(asyn);
    char[] chars = newchar[iRx + 1];
    System.Text.Decoder d = System.Text.Encoding.UTF8.GetDecoder();
    int charLen = d.GetChars(m_DataBuffer, 0, iRx, chars, 0);
    System.String szData = new System.String(chars);
    if (isNewData)
    {
    isNewData = false;
    receivedData = szData;
    }
    else
    {
    receivedData = receivedData + szData;
    }
    WaitForData();
    }
    
    
    // Fonction sendMessage
    // -- Sert a envoy‚ un message … l'h“te de la connection client
    // -- Re‡oit en parametre un message de type string
    // -- Envoie un erreur … la console si il y a un problŠme
    publicvoid sendMessage(String message)
    {
    try
    {
    message = message + "\r\n";
    byte[] byData = System.Text.Encoding.ASCII.GetBytes(message);
    isNewData = true;
    client.Send(byData);
    WaitForData();
    }
    catch (SocketException se)
    {
    MessageBox.Show(se.Message);
    }
    }
    publicstring getMessage()
    {
    string retour;
    if (receivedData != "")
    {
    retour = receivedData;
    }
    else
    {
    retour = "ChaŒne vide!";
    }
    return retour;
    }
    
    ce code est appelé par un bouton dans un formulaire extérieur de cette façon :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    unClient.sendMessage(message);
    reponse = unClient.getMessage();
    
    Il semble que la variable réponse soit rempli trop rapidement car la réponse attendu du serveur arrive après son affectation par "getMessage()"

    Y aurait-il un mécanisme que je pourrait utilisé pour différé son affectation, ou une technique qui m'échappe, car je suis un peu nouveau dans ce type d'opérations.

    Merci
    FadeOut

  2. #2
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Le problème à mon avis, c'est dans ton envoi de message

    La méthode WaitForData n'est pas bloquante (elle porte mal son nom donc), car tu effectues un appel asynchrone dans cette méthode. Résultat, ta méthode sendMessage rend la main avant que tu ais reçu toutes les données et c'est pourquoi ton getMessage ne te renvoie pas le résultat attendu.

    Il faudrait que tu fournisses un événement pour indiquer la fin de la réception (pour rester dans de l'asynchrone) afin de récupérer les données

  3. #3
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 74
    Par défaut
    Serait-il possible de rendre waitfordata bloquante??? Je suis un peu perdu dans ce genre d'opérations... Il semble que celles-ci s'apparentent au Thread.

    Si je voulais créer cet évenement?? de quelle façon devrais-je m'y prendre???


    Merci

  4. #4
    Membre expérimenté
    Avatar de StormimOn
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Mai 2005
    Messages
    2 593
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Sarthe (Pays de la Loire)

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

    Informations forums :
    Inscription : Mai 2005
    Messages : 2 593
    Par défaut
    Tu peux rendre le tout bloquant oui, il suffit de ne pas utiliser les méthodes asynchrones pour la réception des données. Utilise la méthode Receive qui est bloquante

    En gros tu fais un appel à Receive et si tu as reçu des données tu boucles pour de nouveau faire un Receive jusqu'à ce tu ais reçu toutes les données.

  5. #5
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 743
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 743
    Par défaut
    synchrone ou pas, rien ne devrait empêcher le serveur d'expédier ses données en plusieurs messages et le client devrait pouvoir les lire avec une taille de buffer quelconque.
    Cela suppose un minimum de protocole pour convenir de ce que sont les unités d'information échangées.
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Octobre 2006
    Messages
    74
    Détails du profil
    Informations personnelles :
    Localisation : Canada

    Informations forums :
    Inscription : Octobre 2006
    Messages : 74
    Par défaut
    j'ai trouvé cette fonction sur internet, mais encore là, il faut présumé que nous savons le nombre de byte que nous allons recevoir...

    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
    privatestaticvoid Receive(Socket socket, byte[] buffer, int offset, int size, int timeout)
    {
    int startTickCount = Environment.TickCount;
    int received = 0; // how many bytes is already received
    do
    {
    if (Environment.TickCount > startTickCount + timeout)
    thrownewException("Timeout.");
    try
    {
    received += socket.Receive(buffer, offset + received, size - received, SocketFlags.None);
    }
    catch (SocketException ex)
    {
    if (ex.SocketErrorCode == SocketError.WouldBlock ||
    ex.SocketErrorCode == SocketError.IOPending ||
    ex.SocketErrorCode == SocketError.NoBufferSpaceAvailable)
    {
    // socket buffer is probably empty, wait and try again
    Thread.Sleep(30);
    }
    else
    throw ex; // any serious error occurr
    }
    } while (received < size);
    }
    

    je cherche une façon de pouvoir contourner ce problème....

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

Discussions similaires

  1. Réponses: 0
    Dernier message: 19/06/2015, 10h53
  2. envoi / reception de messages
    Par Snowflake dans le forum C
    Réponses: 4
    Dernier message: 05/01/2006, 14h13
  3. [.NET] Une question technique a propos du mode asynchrone
    Par nicknolt dans le forum Général Dotnet
    Réponses: 4
    Dernier message: 08/06/2004, 10h07
  4. [MFC]Pb de reception des messages!
    Par thief dans le forum MFC
    Réponses: 18
    Dernier message: 03/03/2004, 13h05
  5. Sockets + Receptions de messages
    Par raf_gug dans le forum MFC
    Réponses: 14
    Dernier message: 07/11/2003, 10h29

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