Forum |  HardWare.fr | News | Articles | PC | S'identifier | S'inscrire | Shop Recherche
1560 connectés 

  FORUM HardWare.fr
  Programmation
  C

  Communication programmes C

 


 Mot :   Pseudo :  
 
Bas de page
Auteur Sujet :

Communication programmes C

n°2113876
filoo85
Posté le 29-11-2011 à 16:56:02  profilanswer
 

Bonjour à tous,
j'ai deux applications en C, la première contient une structure, et j'aimerai accéder à cette structure à partir de la deuxième application afin de pouvoir lire et écrire dans cette structure.
donc j'aimerai faire communiquer ces deux programmes en C.
J'ai vu qu'on peut utiliser la mémoire partagé pour le faire, mais je ne sais pas vraiment comment faire.
Si quelqu'un peut m'aider svp.
 
Merci d'avance.
 

mood
Publicité
Posté le 29-11-2011 à 16:56:02  profilanswer
 

n°2113881
olivthill
Posté le 29-11-2011 à 17:13:50  profilanswer
 

C sur Windows, ou C sur Unix, ou autre.
 
Avec Windows, on peut envoyer un message, de type "User-defined message", à l'autre application et passer des données en paramètre. L'autre application peut capter ce message dans sa boucle de gestion des messages, et agir en conséquence. Il est aussi possible de mettre les données dans le presse-papier (clipboard).
 
Avec Unix, on peut utiliser la mémoire partagée. Voir http://en.wikipedia.org/wiki/Inter [...] munication .

n°2113933
xilebo
noone
Posté le 29-11-2011 à 20:32:04  profilanswer
 

Tu as un large choix de moyen de communiquer entre différents processus : les mécanismes IPC ( file de message, shared memory ), les tubes , de simples fichiers, des sockets, des communications réseaux.  
 
Certains n'existent que sous Unix, d'autres sous windows également.
 
Après, il faut choisir le moyen le plus adapté à ce que tu souhaites faire.

n°2113970
filoo85
Posté le 30-11-2011 à 09:30:08  profilanswer
 

Bonjour, et merci pour vos réponses.
 
Actuellement mes deux applications communiquent via un fichier.
Application 1 modifie le fichier, Application 2 lie le fichier et va modifier dans la structure où sont stockés les données du fichier.
sauf que ce traitement prend du temps, d’où le choix d'aller directement modifier les valeurs dans la structure pour un traitement plus rapide.
Mes deux application sont sur Windows et en C.
Voila donc je ne sais ce qui est le plus adapté.  
 
Merci d'avance.
 

n°2113998
xilebo
noone
Posté le 30-11-2011 à 11:23:01  profilanswer
 

Sous windows, tu peux utiliser les shared memory file : http://msdn.microsoft.com/en-us/library/dd997372.aspx
 
Attention cependant, c'est du code non portable, et l'exemple que je te donne nécessite .net framework.
 
Il me semble qu'il existe une version win32 au cas où tu ne puisses pas utiliser .net framework ( car c'est pas du C, c'est du C++ managé made in microsoft ).
 
Sinon, si tu veux une solution portable, une solution est de communiquer via une socket réseau, en mode connecté ou non. ( man socket/open/connect/accept/bind/send/recv/close/shutdown sous google ).

n°2114060
filoo85
Posté le 30-11-2011 à 16:48:31  profilanswer
 

Merci xilebo pour ta réponse,
 
Voila j'ai suivi ton conseil et j'ai regardé un peu les sockets.
j'ai fait deux applications pour tester le fonctionnement des sockets avant d'attaquer mon projet.
j'ai fait un programme serveur et un client.
Dans mon programme serveur j'ai crée une structure Personnage qui contient le nom, le prénom et l'age.
Ensuite j'ai déclaré une variable Personnage et j'ai rempli ses composants:
J'ai réussi à envoyer les valeurs de cette structure à mon programme client.
 
Ma question est comment je pourrai à partir de mon programme Client changer par exemple les valeurs age, nom et prénom.
 
Merci d'avance


Message édité par filoo85 le 02-12-2011 à 09:59:12
n°2114136
boblenain2​00
Posté le 01-12-2011 à 06:38:39  profilanswer
 

Pareil mais dans l'autre sens (client->serveur)? :)

n°2115123
filoo85
Posté le 06-12-2011 à 13:59:42  profilanswer
 

Bonjour,
 
la communication entre mon code serveur et mon code client marche avec les socket, mais je n'arrive pas à envoyer les données à partir du client vers le serveur, j'ai essayé de mettre un send dans mon client mais ça ne marche pas.
donc je n'arrive pas à communiquer dans l'autre sens client -> serveur, si quelqu'un peut m'aider.
 
Voila mon code serveur :  

Code :
  1. /* Socket et contexte d'adressage du serveur */
  2.     SOCKADDR_IN sin;
  3.     SOCKET sock;
  4.     socklen_t recsize = sizeof(sin);
  5.    
  6.     /* Socket et contexte d'adressage du client */
  7.     SOCKADDR_IN csin;
  8.     SOCKET csock;
  9.     socklen_t crecsize = sizeof(csin);
  10.     char buffer[32] = "hello serveur";
  11.     int sock_err;
  12.    
  13.    
  14.     if(!erreur)
  15.     {
  16.         /* Création d'une socket */
  17.         sock = socket(AF_INET, SOCK_STREAM, 0);
  18.        
  19.         /* Si la socket est valide */
  20.        if(!erreur)
  21.     {
  22.         sock = socket(AF_INET, SOCK_STREAM, 0);
  23.         /* Si la socket est valide */
  24.         if(sock != INVALID_SOCKET)
  25.         {
  26.             printf("La socket %d est maintenant ouverte en mode TCP/IP\n", sock);
  27.             /* Configuration */
  28.             sin.sin_addr.s_addr    = htonl(INADDR_ANY);   /* Adresse IP automatique */
  29.             sin.sin_family         = AF_INET;             /* Protocole familial (IP) */
  30.             sin.sin_port           = htons(23);         /* Listage du port */
  31.             sock_err = bind(sock, (SOCKADDR*)&sin, sizeof(sin));
  32.             /* Si la socket fonctionne */
  33.             if(sock_err != SOCKET_ERROR)
  34.             {
  35.                 /* Démarrage du listage (mode server) */
  36.                 sock_err = listen(sock, 5);
  37.                 printf("Listage du port %d...\n", 23);
  38.                 /* Si la socket fonctionne */
  39.                 if(sock_err != SOCKET_ERROR)
  40.                 {
  41.                     /* Attente pendant laquelle le client se connecte */
  42.                     printf("Patientez pendant que le client se connecte sur le port %d...\n", 23);       
  43.                     csock = accept(sock, (SOCKADDR*)&csin, &recsize);
  44.                     printf("Un client se connecte avec la socket %d de %s:%d\n", csock, inet_ntoa(csin.sin_addr), htons(csin.sin_port));
  45.     sprintf(monPersonnage.nom, "Martin" );
  46.     sprintf(monPersonnage.prenom, "Dupont" );
  47.     monPersonnage.age = 25;
  48.                     sock_err = send(csock, &monPersonnage, sizeof(monPersonnage), 0);
  49.                     if(sock_err != SOCKET_ERROR)
  50.                         printf("Chaine envoyée : %s\n", buffer);
  51.                     else
  52.                         printf("Erreur de transmission\n" );
  53.                     /* Il ne faut pas oublier de fermer la connexion (fermée dans les deux sens) */
  54.                     shutdown(csock, 2);
  55.                 }
  56.             }
  57.             /* Fermeture de la socket */
  58.             printf("Fermeture de la socket...\n" );
  59.             closesocket(sock);
  60.             printf("Fermeture du serveur terminee\n" );
  61.         }


 et voila mon code Client:
 

Code :
  1. WSADATA WSAData;
  2.     int erreur = WSAStartup(MAKEWORD(2,2), &WSAData);
  3.     SOCKET sock;
  4.     SOCKADDR_IN sin;
  5. char buffer[32] = "";
  6.    if(!erreur)
  7.     {
  8.         /* Création de la socket */
  9.         sock = socket(AF_INET, SOCK_STREAM, 0);
  10.         /* Configuration de la connexion */
  11.         sin.sin_addr.s_addr = inet_addr("127.0.0.1" );
  12.         sin.sin_family = AF_INET;
  13.         sin.sin_port = htons(23);
  14.         /* Si l'on a réussi à se connecter */
  15.         if(connect(sock, (SOCKADDR*)&sin, sizeof(sin)) != SOCKET_ERROR)
  16.         {
  17.             printf("Connection à %s sur le port %d\n", inet_ntoa(sin.sin_addr), htons(sin.sin_port));
  18.            
  19.             /* Si l'on reçoit des informations : on les affiche à l'écran */
  20.   if(recv(sock, &monPersonnage, sizeof(monPersonnage), 0) != SOCKET_ERROR){
  21.                 printf("Recu client : %d\n", monPersonnage.age);
  22.    printf("Recu client : %s\n", monPersonnage.nom);
  23.    printf("Recu client : %s\n", monPersonnage.prenom);
  24.         }
  25.  }
  26.         /* sinon, on affiche "Impossible de se connecter" */
  27.         else
  28.         {
  29.             printf("Impossible de se connecter\n" );
  30.         }
  31.         /* On ferme la socket */
  32.         closesocket(sock);
  33.         #if defined (WIN32)
  34.             WSACleanup();
  35.         #endif
  36.     }
  37.     /* On attend que l'utilisateur tape sur une touche, puis on ferme */
  38.     getchar();
  39.     return EXIT_SUCCESS;
  40. }


Message édité par filoo85 le 06-12-2011 à 14:04:18
n°2115165
xilebo
noone
Posté le 06-12-2011 à 15:10:48  profilanswer
 

je ne sais pas si le recv est bloquant ou non par défaut, mais s'il ne l'est pas, et que les données n'ont pas encore été envoyées, c'est normal que tu ne les recoives pas.
 
Voir la fonction select pour écouter avec attente. ( si select retourne qu'il y a des datas, faire le recv à ce moment là ).
 
 
Attention aussi lors de l'envoi de données ( des entiers 32bits par exemple) sur le réseau si les machines n'ont pas la même endianess.

n°2115169
filoo85
Posté le 06-12-2011 à 15:34:31  profilanswer
 

Désolé, mais je n'ai pas compris ce qu'il faut faire, la j'ai posté le code qui permet de transmettre des données du code serveur au code client, et ça marche.
Ce que je ne sais pas faire et d'envoyer des données de mon code Client à mon code serveur.
Donc qu'est ce qu'il faut ajouter à mon code client pour qu'il puisse envoyer des données via les sockets au code serveur.

mood
Publicité
Posté le 06-12-2011 à 15:34:31  profilanswer
 

n°2115174
xilebo
noone
Posté le 06-12-2011 à 15:49:32  profilanswer
 

C'est le meme code mais dans l'autre sens. Ton client fait un send, et ton serveur un recv. Par contre, il faut veiller à être bien synchronisé pour que le recv du serveur soit bien fait après le send du client.

n°2115191
filoo85
Posté le 06-12-2011 à 17:23:20  profilanswer
 

Peux tu stp me montrer dans mon code ou est ce qu'il faut mettre le send dans le code client, car je suis un peu perdu.
Je l'ai mis avant la fermeture de la socket mais ça ne marche pas.et pareil pour le code serveur j'ai mis le recv avant la fermeture de la socket.
Merci d'avance.

n°2115193
xilebo
noone
Posté le 06-12-2011 à 17:29:19  profilanswer
 

comme je t'ai dit plus haut, si ton recv retourne avant que le send soit fait, il va rien recevoir et quitter. Il faut donc que ton recv attende un temps suffisant ( par exemple une seconde ) avant de considérer qu'il ne recevra pas de données.
 
Tu fais ça avec un select de la façon suivante :
 

Code :
  1. timeval t;
  2. t.tv_sec = 1;
  3. t.tv_usec = 0; // 1000ms de timeout
  4. int valret;
  5. int lenret;
  6. fd_set ensemble;
  7. FD_ZERO(&ensemble);
  8. FD_SET(ma_socket,&ensemble);
  9. valret = select( ma_socket+1, &ensemble, 0, 0, &t);
  10. // tester les différents cas de valret
  11. // le cas qui dit qu'on a recu des données avant 1 seconde est le suivant :  
  12. if(FD_ISSET(ma_socket,&ensemble)!=0) // des données sont recues
  13. {
  14. lenret= recv(ma_socket,buffer,tailledubuffer,0);
  15. }


 
select va attendre jusqu'à 1 seconde pour voir si des données ont été reçues. Si avant 1 seconde c'est le cas, select retourne immédiatement avec une valeur de retour t'indiquant que des données sont reçues, il te suffit alors de faire un recv derrière pour les récupérer.
 
je te laisse l'adapter à ton code.


Message édité par xilebo le 06-12-2011 à 17:31:11
n°2115212
tpierron
Posté le 06-12-2011 à 20:03:44  profilanswer
 

Quelques remarques :

  • recv() pour les sockets TCP (SOCK_STREAM) est bloquant, le select() est inutile pour attendre les données. Pour rendre l'appel non-bloquant il faut passer par ioctlsocket() (Windows) ou fcntl() (le reste).
  • Les sockets sont bidirectionnelles, du peux appeler recv/send du client ou du serveur. À faire attention tout de même: si le client et le serveur appellent recv() alors qu'aucune donnée n'a été envoyée: bah tes processus vont attendre indéfiniements (là le select() peux être utile pour éviter ce genre de problème).
  • Tu écris des données binaire brute dans une socket. Je me doute que tu utilise ça sur la même machine, et le même compilateur pour le client et le serveur. Fait quand même gaffe aux problèmes d'endianess, padding et alignement des structures (classique, mais on oublie vite).


Aller à :
Ajouter une réponse
  FORUM HardWare.fr
  Programmation
  C

  Communication programmes C

 

Sujets relatifs
[C#] erreur dans le codeAppeler une librairie dynamique écrite en C dans Fortran sous Linux
[C++] Utiliser un fichier texte comme ressource[C#] Windows+C#+accès à l'AD et GPO
[C] Lecteur port série windows.h (readFile()) + SDL[C#] savoir si un processus est en train de réfléchir, possible ?
Fonction en language C[C] Puissance 4 arbres de possibilité
[C][Gnu] info utilisation memoire, processeur et swap [résolu]fonctionnement getchar en C
Plus de sujets relatifs à : Communication programmes C


Copyright © 1997-2022 Hardware.fr SARL (Signaler un contenu illicite / Données personnelles) / Groupe LDLC / Shop HFR