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

VB.NET Discussion :

class TcpClient et la commande Send/Recceive


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 166
    Par défaut class TcpClient et la commande Send/Recceive
    Bonjour à tous,
    j'ai un petit problème avec tcpclient.
    J'ai une appli sur une autre machine à laquelle je me connecte à l'aide de la commande :
    mTcpClient.Client.Connect(Ip, Port)
    La connexion se fait bien car j'arrive à piloter l'autre machine en lui envoyant des commandes.

    En revanche, lorsque j'envoie une commande qui demande une réponse, ça fonctionne aussi, mais avec un "train" de retard. Je m'explique :
    Si je lui envoie :
    - réponds moi "AAA", le client me répond avec qlq chose.
    Je luis renvoie :
    - réponds moi "AAA", le client me répond avec "AAA"
    Je luis renvoie :
    - réponds moi "OOO", le client me répond avec "AAA"
    Je luis renvoie encore :
    - réponds moi "OOO", le client me répond avec "OOO"
    etc...
    Donc le client me répond avec une commande de retard... et là je seche
    Ci dessous le code et si une bonne âme peut m'aider, c'est cool

    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
     
    Protected Function SendCommand_Received(ByRef GETcommand As String) As String
            Dim FinalGetCommand As String = ""
            Dim retour As String = "No data sent"
            FinalGetCommand = "1 " & GETcommand & Chr(0)
     
            Dim msg As Byte() = Encoding.UTF8.GetBytes(FinalGetCommand)
            Dim bytes(255) As Byte
            Try
                ' Blocks until send returns.
                Dim byteCount As Integer = mTcpClient.Client.Send(msg, SocketFlags.None)
     
                ' Get reply from the server.
                byteCount = mTcpClient.Client.Receive(bytes, SocketFlags.None)
                If byteCount > 0 Then
                    retour = Encoding.UTF8.GetString(bytes)
                End If
            Catch e As SocketException
                Return e.ErrorCode
            End Try
            Return retour
     
        End Function
    Merci
    Patrick

  2. #2
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 193
    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 193
    Par défaut
    il nous faudrait le "quelque chose" et le code de l'autre côté
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 166
    Par défaut
    Citation Envoyé par Pol63 Voir le message
    il nous faudrait le "quelque chose" et le code de l'autre côté
    humm!! l'autre coté est une applie qui tourne déjà. Je vais vous donner le retour de la console de cette applie. Je la commente en bleu, les commandes envoyées seront en orange et les réponses de la machine distante sont en rouge :

    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
    Load the scene :
    192.168.1.12 (TCP): receive <1 RENDERER SET_OBJECT SCENE*ITELE/TEST/scenes/MI_LAYER LOAD>
    JOINING SESSION (default): 1EEA5218|1EEA522C|3 (127.000.000.001:08B73150,08B73180,1EF34998)
    //- SESSION DUMP ----------------------------------------------------
      SESSION-ID (ip): SESSION |STATE |REF (peers SOCKETS) (port name)
      127.000.000.001: 1EEA5218|1EEA522C|3 (peers not listed) (default)
    //-------------------------------------------------------------------
    192.168.1.12:  answer <1 <14908B8B-1FD4-46E2-9FC7E5D8C09B3362>>
    NONE: receive <>
    
    là j'envoie la commande pour obtenir une réponse, j'attends : 1 mon gtexte :
    192.168.1.12 (TCP): receive <1 RENDERER*TREE*$object$control$FR_TEXTE*GEOM*TEXT GET>
    192.168.1.12:  answer <1 mon texte
    >
    ici je reçois le contenu du "tampon précédent : 1 <14908B8B-1FD4-46E2-9FC7E5D8C09B3362>
    Je renvoie à nouveau la commande
    192.168.1.12 (TCP): receive <1 RENDERER*TREE*$object$control$FR_TEXTE*GEOM*TEXT GET>
    192.168.1.12:  answer <1 mon texte
    >
    Là je reçois bien ce que je demande... donc avec un train de retard
    Y aurait-il autre chose à ajouter dans la connexion au client ?
    En revanche quand j'envoie d'autre commandes, le client les exécute directement, sans "temps" de retard. J'ai ce retard juste quand je fais une requete send/receive... il faut savoir que mon sub de send (simple) est tres simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    Dim FinalGetCommand As String = ""
            Dim retour As String = "No data sent"
            FinalGetCommand = "1 " & GETcommand & Chr(0) 
            Dim msg As Byte() = Encoding.UTF8.GetBytes(FinalGetCommand)
            Try
                ' Blocks until send returns.
                Dim byteCount As Integer = mTcpClient.Client.Send(msg, SocketFlags.None)
    Voila, j'espere que cela vous "aidera" à m'aider... sinon, je verrai autrement.
    Patrick

  4. #4
    Expert éminent Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 193
    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 193
    Par défaut
    si à la connexion le serveur t'envoie un message, et que tu ne lis pas, tu le verras lors du 1er receive, donc après le 1er envoi

    en fait receive est bloquant jusqu'à que ce que le buffer contienne quelque chose, s'il contient déjà quelque chose ca ne bloque pas et tu a les octets

    par contre si tu fais send puis receive tout de suite alors qu'il y a des données dans le buffer, la réponse que tu vas avoir est ce qu'il y avait dans le buffer avant

    ca pourrait éxpliquer ce qui t'arrives
    pour le vérifier c'est simple :

    system.threading.thread.sleep(1000) entre le send et le receive
    si dans la reception tu as ton [quelque chose] + la 1ère réponse que tu attends ca veut dire que le buffer était bien plein avant ton send

    c'est d'ailleurs pour cette raison que dans la plupart des cas quand on fait du tcp/ip, on vérifie la réponse et son format pour voir si c'est bien ce qu'on attend, car les données se concatènent dans le buffer
    on a alors recours à un caractère de fin de trame ou une taille précisée pour pouvoir découper le message
    par ailleurs un message dépassant la taille du buffer sera découpée (8ko sur du tcp/ip je crois, 255 octets dans ton cas comme défini dans le tableau d'octet utilisé dans receive), plusieurs receive sont alors nécessaire pour avoir la trame complète
    en haut niveau, on est souvent obligé de passer par beginsend et beginreceive avec un traitement de découpage de trame
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  5. #5
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 166
    Par défaut
    Bonjour Pol63,
    Ton explication est très intéressante et m'apporte un début de solution.
    En fait, j'ai testé avec system.threading.thread.sleep(2000) entre le send et receive, mais ce n'est pas ce à quoi je m'attendais... Comme tu me l'as écris, j'aurai du avoir tout le paquet du buffer, mais non, j'ai toujours un train de retard
    Dans le commentaire de console de la machine distante, je commence par la commande de "Load scene" (ligne de 1 à 2). Les lignes de 3 à 7 m'informe que j'ai rejoins la session, puis en ligne 8 c'est la réponse de l'élément chargé dans la machine distante. Mais ce que tu ne vois pas, c'est que je me suis connecté avant d'envoyer une commande de Load scene.
    Ma question est : Pourquoi j'ai une réponse de joining session après l'envoi de chargement de scene, alors que la connection (tcpclient.client.connect) a été faite avant le load scene ?
    A en croire la console, j'ai déjà un train de retard au démarrage de ma session tcp.
    Donc en fouillant un peu il me faudrait une com asynchrone entre les 2 machines... j'ai un peu regardé ça et cela ne semble pas si simple à mettre en place... Si tu as déjà qlq chose de simple comme : Send et receive... je suis preneur ou bien si tu as de l'infos là dessus.
    Merci
    Patrick

  6. #6
    Membre confirmé
    Homme Profil pro
    Inscrit en
    Septembre 2012
    Messages
    166
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Septembre 2012
    Messages : 166
    Par défaut
    Bonjour à tous et Pol63.
    J'ai enfin résolu mon problème de communication. Il fallait juste lire la bonne partie de la documentation microsoft.
    avant le code suivant, il faut ouvrit la connexion tcpclient.client.connect (ip, port) :
    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
     
    Dim netStream As NetworkStream = tcpClient.GetStream()
            If netStream.CanWrite Then
               Dim sendBytes As [Byte]() = Encoding.UTF8.GetBytes("Is anybody there?")
               netStream.Write(sendBytes, 0, sendBytes.Length)
            Else
               Console.WriteLine("You cannot write data to this stream.")
               tcpClient.Close()
               ' Closing the tcpClient instance does not close the network stream.
               netStream.Close()
               Return
            End If
            If netStream.CanRead Then
     
               ' Reads the NetworkStream into a byte buffer.
               Dim bytes(tcpClient.ReceiveBufferSize) As Byte
               ' Read can return anything from 0 to numBytesToRead. 
               ' This method blocks until at least one byte is read.
               netStream.Read(bytes, 0, CInt(tcpClient.ReceiveBufferSize))
     
               ' Returns the data received from the host to the console.
               Dim returndata As String = Encoding.ASCII.GetString(bytes)
               Console.WriteLine(("This is what the host returned to you: " + returndata))
            Else
               Console.WriteLine("You cannot read data from this stream.")
               tcpClient.Close()
               ' Closing the tcpClient instance does not close the network stream.
               netStream.Close()
               Return
            End If
    Ce code règle mon soucis de "train de retard".
    Je pense que d'autres méthodes de tcpclient peuvent aussi fonctionner, mais là, je n'ai pas le temps de les tester
    Merci à tous.
    Patrick

Discussions similaires

  1. Class tcpclient delay socketexeption
    Par chuko dans le forum C#
    Réponses: 0
    Dernier message: 23/03/2010, 00h43
  2. Prado : créer des classe en ligne de commande
    Par youtch dans le forum Bibliothèques et frameworks
    Réponses: 4
    Dernier message: 30/06/2009, 11h16
  3. Lancement de classe en ligne de commande
    Par Switche dans le forum Général Java
    Réponses: 2
    Dernier message: 02/02/2009, 16h57
  4. Réponses: 4
    Dernier message: 08/03/2006, 11h43
  5. [Réseau] A propos de la commande « Net Send »
    Par Furius dans le forum Administration
    Réponses: 23
    Dernier message: 06/10/2005, 13h12

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