Envoie de données c++

Envoie de données c++ - C++ - Programmation

Marsh Posté le 03-01-2012 à 16:28:12    

Bonjour à tous, j'ai besoin de votre aide svp,
 
je travail sur le code source d'un logiciel, afin de l'adapter à mes besoins, ce logiciel est programmé en c++.
j'aimerai envoyer au logiciel des données à partir d'un code c (j'utilise les sockets).
le logiciel fait les traitements nécessaires.
Ensuite il me renvoie les résultats dans mon code c (via socket aussi).
 
l'envoie des données au logiciel se fait bien, car j'envoie juste une chaine de caractère par socket.
Pour les résultats, je ne sais pas comment envoyer un tableau par socket.
 
voila la fonction qui affiche la liste des résultats:

Code :
  1. void SIM::print_results(double x)
  2. {
  3.     if (!IO::plotout.any()) {
  4.                     _out.setfloatwidth(OPT::numdgt, OPT::numdgt+6);
  5.                     assert(x != NOT_VALID);
  6.                     _out << x;
  7.                      double res[5];
  8.                     for (PROBELIST::const_iterator
  9.                        p=printlist().begin();  p!=printlist().end();  ++p) {
  10.                      for(int i =0;i<sizeof(p);i++)
  11.                         {
  12.                         res[i]= p->value(); //le tableau à envoyer par socket
  13.                         _out << p->value();
  14.                            }
  15.                       }
  16.                       _out << '\n';
  17.                     }


 
Donc comment envoyer mon tableau de double res avec:

Code :
  1. send(sock, ???,sizeof(buffer), 0);


 
Merci d'avance.


Message édité par lilo_r le 04-01-2012 à 11:46:29
Reply

Marsh Posté le 03-01-2012 à 16:28:12   

Reply

Marsh Posté le 04-01-2012 à 09:14:48    

Quelqu'un pour m'aider svp?

Reply

Marsh Posté le 05-01-2012 à 01:17:56    

du style : send(sock, res, sizeof(res), 0 ); ?
ou sinon send(sock, res[i], sizeof(double), 0 );
(par contre ne faudrait il pas convertir htons/ntoh?)


Message édité par breizhbugs le 05-01-2012 à 01:19:12

---------------
Seul Google le sait...
Reply

Marsh Posté le 05-01-2012 à 09:51:17    

Merci pour ta réponse,
 
je fais bien ça dans mon code serveur:

Code :
  1. send(sock, res[i], sizeof(res), 0 );


 
Et dans mon code client:
 

Code :
  1. if(recv(sock, &res, sizeof(res), 0)!= SOCKET_ERROR)
  2.   {
  3.      printf("Recu client: %f\n", res);
  4.   }


 
mon printf m'affiche 0.0000 (qui correspond pas aux données envoyée).
 
Et dans mon code serveur,je fais après le send:
if(sock_err != SOCKET_ERROR){
                        printf("Chaine envoyee : %0.2f\n",res[i]);
}
Et il m'affiche bien les données qui ont été envoyé.
 
Voila si quelqu'un à une idée.

Reply

Marsh Posté le 05-01-2012 à 11:45:52    

%f c'est pour les float, %lf c'est pour les doubles.
Récupère aussi le retour de recv pour t'assurer qu'il a bien reçu la bonne longueur de données.


---------------
Seul Google le sait...
Reply

Marsh Posté le 05-01-2012 à 12:24:02    

voila ce que je fais maintenant, mais la socket client reçoit une seule valeur au lieu de 2.(j'utilise des float vu que dans mes résultats j'ai de chiffres avec virgule)
dans la console le code affiche les résultats : 5  2.5 (et se sont les valeurs que je veux récupérer dans mon code client)
 
coté serveur:
 
 

Code :
  1. if (!IO::plotout.any()) {
  2.                     _out.setfloatwidth(OPT::numdgt, OPT::numdgt+6);
  3.                     assert(x != NOT_VALID);
  4.                     _out << x;
  5.                   float res[2];
  6.                     for (PROBELIST::const_iterator
  7.                        p=printlist().begin();  p!=printlist().end();  ++p) {
  8.                          for(int i=0;i<sizeof(res);i++)
  9.                            {
  10.                               res[i]= p->value();
  11.                                 _out << p->value();
  12.                                send(csock,(char*)&res[i],sizeof(res), 0);
  13.                    if(sock_err != SOCKET_ERROR){
  14.                         printf("valeur envoyee : %0.2f",res[i]); //ici j'ai bien valeur envoyée 5 et valeur envoyé 2.5
  15.                             }
  16.                     else
  17.                         printf("Erreur de transmission\n" );[/b]
  18.                            }
  19.                        _out << '\n';
  20.                        }


 
coté client :
 

Code :
  1. float res[2];
  2.         if(recv(sock,&res, sizeof(res), 0)!= SOCKET_ERROR)
  3.   {
  4.    float* p = (float*)res;
  5.      printf("Recu client: %0.2f %0.2f\n", p[0],p[1]); // ici j'ai la valeur 5.0 et 0.00
  6.   }


 
peut tu jeter un œil sur mon code stp pour voir ce que je ne fais pas bien.
 
Merci d'avance


Message édité par lilo_r le 05-01-2012 à 12:25:05
Reply

Marsh Posté le 05-01-2012 à 14:45:58    

Coté serveur, tu envoie 2 données (tu es dans une boucle), il faut donc que coté client tu boucles pour recevoir 2 données...


---------------
Seul Google le sait...
Reply

Marsh Posté le 05-01-2012 à 15:45:52    

voila j'ai fait une boucle coté client, mais la deuxième valeur est toujours à 0.00, je ne sais pas vraiment pourquoi:
 

Code :
  1. if(recv(sock,&res, sizeof(res), 0)!= SOCKET_ERROR)
  2.   {
  3.    for (i=0;i<sizeof(res);i++)
  4.    {
  5.         printf("Recu client: %0.2f\n", res[i]);
  6.    }

Reply

Marsh Posté le 05-01-2012 à 17:13:21    

si res est un double faut que tu fasse deux recv(): 1 pour lire le premier, un pour lire le second


---------------
Seul Google le sait...
Reply

Marsh Posté le 05-01-2012 à 17:54:08    

res est: float res[2].
 

Citation :

faut que tu fasse deux recv(): 1 pour lire le premier, un pour lire le second


 
Est ce que tu peux m'en dire un peu plus stp.(sur la syntaxe et les paramètres de chaque recv()).car je ne vois pas comment faire.
 
Merci d'avance.


Message édité par lilo_r le 05-01-2012 à 18:02:03
Reply

Marsh Posté le 05-01-2012 à 17:54:08   

Reply

Marsh Posté le 05-01-2012 à 20:31:29    

Code :
  1. double res;
  2. while(recv(sock,&res, sizeof(res), 0)!=SOCKET_ERROR)
  3. {
  4.      printf("Recu client: %0.2f\n", res);
  5. }


---------------
Seul Google le sait...
Reply

Marsh Posté le 10-01-2012 à 12:08:02    

Merci breizhbugs pour ta réponse ça marche,
 
mais voila  j'ai un autre problème:
 
Dans mon programme c, j'ai 3 fonctions:
 
- une fonction serveur qui m'envoie les commandes à mon logiciel (j'utilise send(csock, &buffer, sizeof(buffer), 0), pour envoyer une chaine de caractère).
- une fonction client qui me permet de récupérer les données du logiciel.
- une fonction client qui me permet de récupérer les données du logiciel.(d'autre données qui m’intéressent).
 
Le problème est que quand je compile le programme, la première fonction serveur se déroule bien (donc j'envoie bien les commandes), ainsi que une fonction client des deux selon celle que j’exécute en premier, ensuite ça reste bloqué donc je ne reçoit plus rien.(donc je récupère la moitié des résultats).
 
Dans le cas ou j’écris les commandes directement dans la console de mon logiciel sans passé par la fonction serveur les résultats des deux fonctions clients s'affichent bien.
 
Est ce que quelqu'un à une explication?  
 
Merci d'avance.

Reply

Marsh Posté le 10-01-2012 à 20:30:12    

Peux pas deviner ce qui va pas sans le code...


---------------
Seul Google le sait...
Reply

Marsh Posté le 11-01-2012 à 10:26:41    

Merci breizhbugs pour ta réponse,
 
Voila le code:
 
Pour l'envoie de commande j'ai la fonction:
 

Code :
  1. int command_send() //code serveur
  2. {
  3.        char buffer[100];
  4. WSADATA WSAData;
  5. int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
  6. SOCKET sock_serv;
  7. SOCKADDR_IN sin;
  8. SOCKET csock;
  9. SOCKADDR_IN csin;
  10. socklen_t recsize = sizeof(csin);
  11. int sock_err;
  12. int PORT = 25;
  13.     /* Si les sockets Windows fonctionnent */
  14.     if(!erreur)
  15.     {
  16.         sock_serv = socket(AF_INET, SOCK_STREAM, 0);
  17.         /* Si la socket est valide */
  18.         if(sock_serv != INVALID_SOCKET)
  19.         {
  20.             printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock_serv);
  21.             /* Configuration */
  22.             sin.sin_addr.s_addr    = htonl(INADDR_ANY);   /* Adresse IP automatique */
  23.             sin.sin_family         = AF_INET;             /* Protocole familial (IP) */
  24.             sin.sin_port           = htons(PORT);         /* Listage du port */
  25.             sock_err = bind(sock_serv, (SOCKADDR*)&sin, sizeof(sin));
  26.             /* Si la socket fonctionne */
  27.             if(sock_err != SOCKET_ERROR)
  28.             {
  29.                 /* Démarrage du listage (mode server) */
  30.                 sock_err = listen(sock_serv, 5);
  31.                 printf("Listage du port %d...\n", PORT);
  32.                 /* Si la socket fonctionne */
  33.                 if(sock_err != SOCKET_ERROR)
  34.                 {
  35.                     /* Attente pendant laquelle le client se connecte */
  36.                     printf("Patientez pendant que le client se connecte sur le port %d...\n", PORT);       
  37.                      csock = accept(sock_serv, (SOCKADDR*)&csin, &recsize);
  38.                      printf("Un client se connecte avec la socket %d de %s:%d\n", csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));
  39.                      sprintf(buffer, "commande " );
  40.                
  41.                           send(csock, &buffer ,500, 0);
  42.   if(sock_err != SOCKET_ERROR){
  43.                           printf("Chaine envoyee : %s\n",buffer);
  44.                       
  45.    }
  46.                    else
  47.                         printf("Erreur de transmission\n" );
  48.   }
  49.                  
  50.             /* Fermeture de la socket */
  51.             printf("Fermeture de la socket...\n" );
  52.          
  53.             printf("Fermeture du serveur terminee\n" );
  54.         }
  55.  }
  56. closesocket(sock_serv);
  57. WSACleanup();
  58.      
  59.     /* On attend que l'utilisateur tape sur une touche, puis on ferme */
  60.     getchar();
  61. }
  62.     return EXIT_SUCCESS;
  63. }


 
Le code coté client:
 

Code :
  1. int command_receive() //réception des commandes coté client
  2. {
  3. char buffer[100];
  4.         WSADATA WSAData;
  5.         int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
  6.         SOCKET sock_serv;
  7.         SOCKADDR_IN sin;
  8. int PORT =25;
  9.     /* Si les sockets Windows fonctionnent */
  10.     if(!erreur)
  11.     {
  12.         /* Création de la socket */
  13.         sock_serv = socket(AF_INET, SOCK_STREAM, 0);
  14.         /* Configuration de la connexion */
  15.         sin.sin_addr.s_addr = inet_addr("127.0.0.1" );
  16.         sin.sin_family = AF_INET;
  17.         sin.sin_port = htons(PORT);
  18.         /* Si l'on a réussi à se connecter */
  19.         if(connect(sock_serv, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
  20.         {
  21.  if(recv(sock_serv, (char *)&buffer, sizeof(buffer), 0) != SOCKET_ERROR)
  22.         printf("resulat : \s",buffer);
  23.         }
  24.         /* sinon, on affiche "Impossible de se connecter" */
  25.         else
  26.         {
  27.             printf("Impossible de se connecter\n" );
  28.         }
  29.         /* On ferme la socket */
  30.         closesocket(sock_serv);
  31.             WSACleanup();
  32.     }
  33.     /* On attend que l'utilisateur tape sur une touche, puis on ferme */
  34.    getchar();
  35.     return EXIT_SUCCESS;
  36. }


 
Merci beaucoup pour ton aide.


Message édité par lilo_r le 18-01-2012 à 11:40:31
Reply

Marsh Posté le 11-01-2012 à 14:48:58    

Bon ca fait beaucoup de code tout ça...
Quand on regarde ton main, tu fais command_send() qui est un code serveur (d'après ton commentaire et d'après le bind) or tu as plutôt l'air d'être dans un client...
Ensuite tu établis une nouvelle connexion pour chaque opération que tu veux faire, je suis pas sûr qu'il s'agisse de la bonne solution.
Ensuite tu utilises des ports trop petits qui sont assigné a des fonctions précises (par exemple le port 25 est celui de smtp par exemple!)
enfin puisque tu n'utilises pas les threads, cela signifie que pour que client2 s'execute, il faut d'abord que command_send()soit valider (bind/accept est bloquant!) puis client1.
Bon je sais pas si l'erreur se trouve quelque par là dedans par contre...


---------------
Seul Google le sait...
Reply

Marsh Posté le 11-01-2012 à 16:09:06    

- pour command_send() pour moi c'est un serveur puisqu'il y a le send et quand on a recv dans le code c'est un client (j’espère que je ne dit pas de bêtise).
- Pour la connexion j'ai fait comme ça car je ne savais pas comment faire autrement (première utilisation de socket donc...).
- je vais utiliser d'autres ports.
- comment je pourrai faire stp pour rendre command_send() et socket_client 1&2 non bloquante? peut être ça résoudra mon problème.
 
(Merci d'avoir pris le temps de regarder mon code je sais qu'il est long mais je ne savais pas ou se trouvait le problème donc j'ai tous posté.)

Message cité 1 fois
Message édité par lilo_r le 11-01-2012 à 16:24:15
Reply

Marsh Posté le 11-01-2012 à 19:05:07    

lilo_r a écrit :


- pour command_send() pour moi c'est un serveur puisqu'il y a le send et quand on a recv dans le code c'est un client (j’espère que je ne dit pas de bêtise).


Non en fait, pour faire simple, un serveur est le programme qui attend (avec accept() ) qu'un client se connecte. L'un et l'autre peuvent utiliser send et recv indépendamment de ce qu'ils soient client ou serveur.  
 

lilo_r a écrit :


- Pour la connexion j'ai fait comme ça car je ne savais pas comment faire autrement (première utilisation de socket donc...).


si le client et le serveur sont toujours les mêmes, il faut définir un protocole de dialogue: si en tant que serveur je reçois telle donnée j'envoie tel autre donnée et je réécoute le client pour savoir ce qu'il veut.
tu peux par exemple définir que tu vas d'abord recevoir un entier qui va selon sa valeur indiquer quelle opération tu veux faire;
0- le serveur attend un client. Quand celui ci ce connecte, il crée un thread qui va s'occuper de ce client. Le serveur continue d'attendre d'autre client dans sa boucle principale et traite un client en particulier dans un thread.
1- si le client envoie un entier de ce qu'il veut (valeur==1 par exemple), tu peut définir qu'ensuite il envoie sa commande (structure de taille fixe) et qu'il attend un entier en retour
2- donc coté serveur, tu lis d'abord un entier, puis quand tu reconnais que 1 a été lu, tu lis la commande. (tu la traite )et tu renvoie un entier pour dont la valeur sert de confirmation par exemple
ensuite le serveur revient à l'etape 1 ou il attend que le client soit répète l'opération, soit demande une autre opération (valeur == 2, 3, 4...) soit mets fin a la communication (valeur==0) .
 

lilo_r a écrit :


- je vais utiliser d'autres ports.
- comment je pourrai faire stp pour rendre command_send() et socket_client 1&2 non bloquante? peut être ça résoudra mon problème.


comme j'ai expliquer plus haut en utilisant des threads.
 
Le mieux est que tu te trouves un exemple sur internet (par exemple le code source d'un serveur de tchat!)


Message édité par breizhbugs le 11-01-2012 à 19:06:03

---------------
Seul Google le sait...
Reply

Marsh Posté le 11-01-2012 à 23:26:09    

Tu peux peut être aussi essayer avec la sfml, je sais pas comment on gère le thread normalement, mais c'est super facile à mettre en place avec et elle a aussi un module réseau assez simple à utiliser :D


---------------
Perhaps you don't deserve to breathe
Reply

Marsh Posté le 12-01-2012 à 11:00:27    

Merci pour vos réponses, je vais regarder tous ça et je vous tiens au courant.

Reply

Marsh Posté le 23-01-2012 à 10:52:41    

Bonjour,  
 
Me revoilà de retour avec une nouvelle question  :)  
 
Voila j'ai fait comme ce que breizhbugs m'a dit j'ai utilisé les Thread pour résoudre mon problème et ça marche.(Merci d’ailleurs pour les explications breizhbugs).
 
Mais maintenant j'ai une autre question:
 
Pour envoyer une commande j'utilise ma fonction command_send(char buffer)(code serveur il contient accept()), et pour les recevoir la fonction commande _receive()(code client).
Si j'ai besoin d'utiliser plusieurs fois command_send(char buffer), je dois avoir autant de fois commande _receive() de l'autre coté sinon ça marche pas (les résultats ne s'affichent pas).
 
Donc comment je pourrai faire pour pouvoir utiliser command_send(char buffer) autant de fois que je veux, mais avoir de l'autre coté une seule fois commande_receive() dans une boucle par exemple (j'ai pensé à une boucle mais je ne sais pas quels paramètres lui passé (condition d'arrêt etc...)).
 
Donc si vous avez des idées pour m'aider svp n'hésiter pas.
 
Merci d'avance.


Message édité par lilo_r le 24-01-2012 à 17:05:03
Reply

Marsh Posté le 24-01-2012 à 17:04:38    

Quelqu'un pour m'aider svp?

Reply

Marsh Posté le    

Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed