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 :

Methode d'envoie et de récéption TCP


Sujet :

C#

  1. #1
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 32
    Points : 17
    Points
    17
    Par défaut Methode d'envoie et de récéption TCP
    Bonjour.

    J'ai un petit programme Visual C# qui me permet d'envoyer deux données distinct à un serveur TCP.
    Mon code s'apparente à sa:

    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
     
    System.Net.Sockets.TcpClient tcpclient = null;
                try
                {
                    /*script de lecture*/
                    //ip
                    string urlSave = "C:\\SaveIP.txt";
                    StreamReader smIP = new StreamReader(urlSave);
                    string textIP = smIP.ReadLine();
     
                    /*script de'envoi*/
                    //teste co
                    tcpclient = new TcpClient(textIP, 9999);
                    AfichTime.Text = "Connection Ok";
     
                    //récupération des variable des box
                    string EnvoiData1 = mData1.Text;
                    string EnvoiData2 = mData2.Text;
     
                    try
                    {
                        //trame 
                        NetworkStream nstream = tcpclient.GetStream();
                        StreamWriter sw = new StreamWriter(nstream);//ecrir un flu
                        StreamReader sr = new StreamReader(nstream);//lire un flux
     
                        sw.Write("Hello! Data1: {0} Data2: {1}", EnvoiData1, EnvoiData2);
                        sw.Flush();
     
                        AfichTime.Text = "Envoi!";
                    }
                    catch
                    {
                        AfichTime.Text = "Erreur envoi!";
                    }
     
                }
                catch
                {
                    AfichTime.Text = "Erreur de connexion";
                }
    Mon problème réside dans le fait que je doit cliquer plusieurs fois sur le bouton d'envoi pour que le serveur les reçoivent. mais j'aimerais envoyer une seul trame. Je ne comprend pas pourquoi la méthode Flush() ne force pas l'envoie immédiat de la trame.

    Merci de tout coup de pouce.

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

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 175
    Points : 25 116
    Points
    25 116
    Par défaut
    le flush me parait étrange, il me semble que ca sert à vider le tampon ...

    si c'est toi qui a codé le serveur, il serait intéressant d'avoir le code

  3. #3
    Membre actif
    Profil pro
    Inscrit en
    Février 2006
    Messages
    197
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Février 2006
    Messages : 197
    Points : 279
    Points
    279
    Par défaut
    Déjà, tu n'es pas obligé de passer par un NetworkStream.
    Tu peux utiliser directement le GetStream() de ton TcpClient pour créer ton StreamReader et ton StreamWriter.

    Si tu n'envoie qu'une seule ligne, tu peux utiliser la méthode WriteLine().

    Après, il y a des chances que ça vienne du serveur aussi.
    Ton serveur doit être en attente d'un packet (c'est le streamReader.ReadLine() du côté serveur qui s'en occupe).

    Il faut tout d'abord se mettre en attente de la connexion
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    server = new TcpListener(IPAddress.Any, 9999);
    	while (true) {
    		server.Start();
    		if (server.Pending()) {
    			TcpClient connection = server.AcceptTcpClient();
    Après il faut de préférence gérer les connexions avec des thread (sauf cas spécifique).
    Il suffit de créer une class dans laquelle tu créé ton thread et dans ta méthode run() tu y mets le code de lecture.
    Et tu instanciera ton objet en dessous de server.AcceptTcpClient().

    Le Flush semble correcte, en général on l'utilise bien après Write() ou le WriteLine().

    Si tu montre ton code serveur, on pourra peut-être t'aider plus.

  4. #4
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 32
    Points : 17
    Points
    17
    Par défaut
    Merci de vos répondes

    Voila mon serveur: il est en C.

    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
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
     
    #include <stdio.h>
    #include <stdlib.h>
    #include <errno.h>
    #include <string.h>
    #include <sys/types.h>
    #include <netinet/in.h>
    #include <sys/socket.h>
    #include <sys/wait.h>
    #include <unistd.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <sys/un.h>
     
    #define MYPORT 9999
    #define BACKLOG 5
    #define MAXCLIENTS 1
    #define MAXDATASIZE 100
     
    int main(void)
    {
       int sockfd,new_fd,numbytes,highest = 0,i;
       int clients[MAXCLIENTS];
       int buffer[MAXDATASIZE] ;
     
       struct sockaddr_in my_addr,their_addr;
       socklen_t sin_size;
       struct timeval tv;
       fd_set readfds;
     
       if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
         perror("socket");
         exit(-1);
       }
       my_addr.sin_family = AF_INET;
       my_addr.sin_port = htons(MYPORT);
       my_addr.sin_addr.s_addr = INADDR_ANY;
       bzero(&(my_addr.sin_zero), 8);
     
       if (bind(sockfd, (struct sockaddr *)&my_addr, sizeof(struct sockaddr)) == -1) {
          perror("bind");
          exit(-1);
       }
       if (listen(sockfd, BACKLOG) == -1) {
          perror("listen");
          exit(-1);
       }
       bzero(clients,sizeof(clients));
       highest = sockfd ;
       while(1) {
          sin_size = sizeof(struct sockaddr_in);
          tv.tv_sec = 0;
          tv.tv_usec = 250000;
          FD_ZERO(&readfds);
          for ( i = 0 ; i < MAXCLIENTS ; i ++ ) {
             if ( clients[i] != 0 ) {
                FD_SET(clients[i],&readfds);
             }
          }
          FD_SET(sockfd,&readfds);
          if (select(highest+1, &readfds, NULL, NULL, &tv) >=0 ) {
             if (FD_ISSET(sockfd, &readfds)) {
                if ((new_fd = accept(sockfd, (struct sockaddr *)&their_addr, &sin_size)) == -1) {
                   perror("accept");
                   continue;
                }
                for( i = 0 ; i < MAXCLIENTS ; i ++ ) {
                   if ( clients[i] == 0 ) {
                      clients[i] = new_fd ;
                      break;
                   }
                }
                if ( i != MAXCLIENTS ) {
                   if ( new_fd > highest ) {
                      highest = clients[i] ;
                   }
                   printf("Connexion received from %s (slot %i) ",inet_ntoa(their_addr.sin_addr),i);
                   send(new_fd,"Vous etes connecte au serveur",65,MSG_NOSIGNAL);
     
                }
                else {
                   send(new_fd, "No room for you ! ",18,MSG_NOSIGNAL);
                   close(new_fd);
                }
             }
             for ( i = 0 ; i < MAXCLIENTS ; i ++ ) {
                if ( FD_ISSET(clients[i],&readfds) ) {
                   if ( (numbytes=recv(clients[i],buffer,MAXDATASIZE,0)) <= 0 ) {
                      printf("Connexion lost from slot %i ",i);
                      close(clients[i]);
                      clients[i] = 0 ;
                   }
                   else {
                      buffer[numbytes] = '0';
                      printf("Received from slot %i : %s",i,buffer);
                      send(new_fd,buffer,10,MSG_NOSIGNAL);
                   }
                }
             }
          }
          else {
             perror("select");
             continue;
          }
       }
       return 0;
    }
    Ici il reçoit les connections telnet, d'où mon idée du tcpclient. Je veux pouvoir crée une connexion plus complexe à l'avenir (je suis encore en une phase de test) afin de faire un échange de données selon une procédure définit.

    Pour le Flush il n'est pas censé forcé l'envoie de donnée?

    Merci

  5. #5
    Membre averti

    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 10
    Points : 348
    Points
    348
    Par défaut
    juste comme ça, la taille de ta chaine dépasserait pas celle du buffer tcp client/serveur?

  6. #6
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 32
    Points : 17
    Points
    17
    Par défaut
    Hello!
    Je comprend pas trop comment celui-ci fonctionne...
    Mon 'ami' Google ne m'a pas offert une très bonne explication si ce n'es que je ne doit pas dépasser les 255bits.
    même si j'envoie un simple "hello!" en texte je suis réduit au même problème.

  7. #7
    Membre averti

    Profil pro
    Inscrit en
    Novembre 2010
    Messages
    10
    Détails du profil
    Informations personnelles :
    Localisation : France, Nord (Nord Pas de Calais)

    Informations forums :
    Inscription : Novembre 2010
    Messages : 10
    Points : 348
    Points
    348
    Par défaut
    attention, une erreur souvent commise (d'après ce que j'ai lu):
    lorsque tu écris en 1 fois x caractères, tu pourra recevoir 1 paquet de x, ou plusieurs paquets de y caractères.

    Après je pense que cela dépend de la configuration de tes sockets et du "hazard".

    C'est pour ça qu'il faut mettre un repère de début et de fin de message sur chaque donnée envoyée.

  8. #8
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 32
    Points : 17
    Points
    17
    Par défaut
    Oui, j'ai modifier le serveur, mai celui-ci affiche parfois des symboles bizarre a la fin du message.
    J'aimerai savoir ou tu a lut sa stp ^^

  9. #9
    Membre à l'essai
    Profil pro
    Étudiant
    Inscrit en
    Novembre 2009
    Messages
    32
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Novembre 2009
    Messages : 32
    Points : 17
    Points
    17
    Par défaut
    Recherche...Recherche...Recherche...Recherche....
    Test...Test...Test...Test...
    Échec...Échec...Échec...Échec...Échec...Échec...Échec...Trouver!!!

    Je peut me débarrasser des caractère étrange a la fin de mes trames; Elles sont bien en fonction de la taille de celle-ci mais une solution apparait: Noter un symbole de fin de trame l'antislash suivi d'un n (comme le fin de ligne en C)

    Merci à tout pour votre aide.

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

Discussions similaires

  1. Envoi structure sur socket TCP
    Par BlackVador dans le forum C
    Réponses: 6
    Dernier message: 05/01/2011, 13h15
  2. submit() et method post (envoie de formulaire en js)
    Par omageus dans le forum Général JavaScript
    Réponses: 1
    Dernier message: 25/05/2009, 19h11
  3. Datastore methode d'envoi AJAX
    Par mapmip dans le forum Ext JS / Sencha
    Réponses: 0
    Dernier message: 29/01/2009, 19h12
  4. Problème avec l'envoi d'une trame TCP
    Par fredoBreton dans le forum API, COM et SDKs
    Réponses: 14
    Dernier message: 17/11/2005, 20h19

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