API win32 + logiciel réseau

API win32 + logiciel réseau - C++ - Programmation

Marsh Posté le 26-04-2006 à 13:53:33    

Bonjour à tous,
 
Voila j'ai
réalisé deux petites applications simples (client et serveur) en mode
console. Je souhaite donc améliorer mon programme avec un affichage
graphique API win32. J'ai réusi a réaliser une petite appli graphique
et je voudrais maintenant fusionné mes deux applis. J'ai essayé et la
le programme plante. Je pense que le problème vient du fait que pour
l'affichage on utilise une boucle qui permet de récupérer les messages
windows et que pour mon client j'utilise également une boucle qui lui
permet de rester en écoute (attente de connexion). Donc les deux
boucles se gène mutuellement.
 
Je vous donne donc les deux codes séparés.
 
D'abord l'appli graphique:
 
-------------------------------------------------------------------

Code :
  1. #include <windows.h>
  2. #include <stdio.h>
  3. HWND CreateWnd(HINSTANCE);
  4. LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
  5. HWND hwnd; //afficher
  6. HWND hBoutonAfficher, hBoutonQuit; //boutons
  7. HWND hEdit; //edit
  8. /****************BOUCLE PRINCIPALE**************************/
  9. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
  10.         MSG msg; //récupère les messages de windows
  11.         //crée la fenetre
  12.         hwnd = CreateWnd(hInstance);
  13.         ShowWindow (hwnd, iCmdShow);
  14.         //crée un bouton Afficher
  15.         hBoutonAfficher = CreateWindow("button", "Afficher", WS_CHILD | WS_BORDER, 5, 60, 100, 30, hwnd, 0, hInstance, 0);
  16.         ShowWindow(hBoutonAfficher, iCmdShow);
  17.         //crée un bouton Quitter
  18.         hBoutonQuit = CreateWindow("button", "Quitter", WS_CHILD | WS_BORDER, 110, 60, 100, 30, hwnd, 0, hInstance, 0);
  19.         ShowWindow(hBoutonQuit, iCmdShow);
  20.        
  21.         //raffraichit la fenetre
  22.         UpdateWindow (hwnd);
  23.    
  24.      while (GetMessage (&msg, NULL, 0, 0)){
  25.           TranslateMessage (&msg);
  26.           DispatchMessage (&msg);
  27.      }
  28.      return msg.wParam;
  29. }
  30. /****************FIN DE LA BOUCLE PRINCIPALE**************************/
  31. /******************CREATION DE LA FENETRE*******************/
  32. HWND CreateWnd(HINSTANCE hInst){
  33.     WNDCLASS     wc;
  34. //définit la classe fenetre
  35. wc.style = 0;
  36. wc.lpfnWndProc = WndProc;
  37. wc.cbClsExtra = 0;
  38. wc.cbWndExtra = 0;
  39. wc.hInstance = NULL;
  40. wc.hIcon = LoadIcon(NULL, IDI_APPLICATION);
  41. wc.hCursor = LoadCursor(NULL, IDC_ARROW);
  42. wc.hbrBackground = (HBRUSH)(1 + COLOR_BTNFACE);
  43. wc.lpszMenuName =  NULL;
  44. wc.lpszClassName = "MaWinClass";
  45.     if(!RegisterClass(&wc)) return FALSE;
  46.    
  47.     //renvoie les données de la fenetre
  48.     return CreateWindow("MaWinClass", "Super appli", WS_OVERLAPPEDWINDOW,
  49.                          CW_USEDEFAULT, CW_USEDEFAULT, 225, 130,
  50.                          NULL, NULL, hInst, NULL);
  51. }
  52. /***************FIN CREATION DE LA FENETRE*******************/
  53. /****************CONTROLE DES RETOURS DE MESSAGES DE WINDOWS**************/
  54. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
  55.     //récupération du message de windows
  56.     switch (message){
  57.         //création des fenetres
  58.         case WM_CREATE:
  59.             //Créer l'éditeur pour taper les chiffres (Nom, style, taille, position, handle(identificateur) , etc..)
  60.  
  61.         hEdit = CreateWindow("EDIT", "192",
  62. WS_CHILD|WS_VISIBLE|WS_BORDER|ES_CENTER, 50, 30, 70, 20, hwnd,
  63. (HMENU)1001, ((LPCREATESTRUCT)lParam)->hInstance, NULL);
  64.             break;
  65.         case WM_COMMAND:
  66.             if((HWND) lParam == hBoutonQuit){
  67.                 if (MessageBox (NULL,"Êtes vous sur de vouloir quitter l'application",
  68.                                         "Super appli", MB_YESNO) == IDYES)
  69.                 {
  70.                     DestroyWindow(hwnd);
  71.                     return 0;
  72.                 }
  73.             }
  74.             else if ((HWND) lParam == hBoutonAfficher){
  75.                 // récupération du texte de l'EDIT
  76.                 int LenghtTexte = GetWindowTextLength(hEdit);
  77.                 char* pBuffer = new char[LenghtTexte + 1];
  78.                 GetWindowText(hEdit, pBuffer, LenghtTexte + 1);
  79.                 MessageBox (NULL,pBuffer , "Super appli", MB_OK);
  80.                 // On libère la mémoire allouée
  81.                 delete[] pBuffer;
  82.             }
  83.         //--lors du rafraichissement de la fenetre (textes, dessins, ...)
  84.         case WM_PAINT:
  85.             //variables
  86.             HDC hdc; PAINTSTRUCT ps;
  87.             hdc = BeginPaint(hwnd,&ps);    // obtient un handle de contexte de périphérique
  88.            
  89.             // un peu de texte
  90.             SetBkColor(hdc,RGB(255,255,255)); //couleur de fond
  91.             SetTextColor(hdc,RGB(0,0,0)); //couleur du texte
  92.             TextOut(hdc,20,5,"SUPER APPLI GRAPHIQUE",strlen("SUPER APPLI GRAPHIQUE" )); //titre de l'application
  93.             TextOut(hdc,7,32,"texte :",strlen("texte :" ));
  94.             break;
  95.         //--lors de la destruction de la fenetre fenetre
  96.         case WM_DESTROY:
  97.             PostQuitMessage (0) ;
  98.             return 0 ;
  99.    
  100.     }
  101.     return DefWindowProc (hwnd, message, wParam, lParam);
  102. }
  103. /****************FIN DU CONTROLE DES RETOURS DE MESSAGES DE WINDOWS**************/


 
-----------------------------------------------------------------
 
Ensuite mon client:
 

Code :
  1. /*************************************************************  
  2.             LE CLIENT  
  3. **************************************************************/
  4. #include <stdio.h>
  5. #include <winsock2.h>
  6. #include <string.h>
  7. #include <time.h>
  8. #pragma comment(lib, "ws2_32.lib" )
  9. #define LG_MAX_REQUETE 1024
  10.  
  11. void traitement(SOCKET);
  12.  
  13. void main()
  14. {
  15.     int val,port=0,erreur;
  16.  
  17.     WSADATA wsa;
  18.     /* initialisation */
  19.     WSAStartup(MAKEWORD(2,0), &wsa);
  20.    
  21.     SOCKET serveur;
  22.     SOCKET client;
  23.     SOCKADDR_IN sin;
  24.     SOCKADDR_IN clientsin;
  25.     /* saisir la configuration du serveur */
  26.     printf("Entrez le numero de port: " );
  27.     scanf("%d",&port);
  28.  
  29.     /* creation de la socket serveur */
  30.     serveur=socket(AF_INET,SOCK_STREAM,0);
  31.     if(serveur==INVALID_SOCKET)
  32.     {
  33.         perror("erreur de creation de la socket" );
  34.         exit(-1);
  35.     }
  36.     /* configuration de la socket */
  37.     sin.sin_addr.s_addr = INADDR_ANY;
  38.     sin.sin_family = AF_INET;
  39.     sin.sin_port = htons(port);
  40.  
  41.     /* attacher le socket au n° de port*/
  42.     erreur=bind(serveur,(SOCKADDR *)&sin, sizeof(sin));
  43.     if(erreur == INVALID_SOCKET)
  44.     {
  45.         perror("bind" );
  46.         exit(-1);
  47.     }
  48.     /* creation d'une file d'attente de demande de connexion */
  49.     listen(serveur,0);
  50.     val=sizeof(clientsin);
  51.     printf("\n\tClient en ecoute\n" );
  52.     while(1)
  53.     {   
  54.         /* accepter une connexion */
  55.         client=accept(serveur,(SOCKADDR *)&clientsin,&val);
  56.         if(client == INVALID_SOCKET)
  57.         {
  58.             perror("erreur de connection" );
  59.             exit(-1);
  60.         }
  61.         /* fonction qui utilise la socket */
  62.         traitement(client);
  63.     }
  64. }
  65. /**************************************************************  
  66.             traitement  
  67.      traite la requete envoyer par le client  
  68. **************************************************************/
  69. void traitement(SOCKET client)
  70. {
  71.     int lg,comparaison;
  72.     char reponse[LG_MAX_REQUETE];
  73.     /* attendre la reception d'une requete sur la socket "client" */
  74.     lg=recv(client,reponse,LG_MAX_REQUETE,0);
  75.     reponse[lg]='\0';
  76.     comparaison=strcmp(reponse,"arret" );
  77.     if(comparaison==0)
  78.     {
  79.         system("shutdown -s" );
  80.     }
  81.     comparaison=strcmp(reponse,"redemarrage" );
  82.     if(comparaison==0)
  83.     {
  84.         system("shutdown -r" );
  85.     }
  86.     comparaison=strcmp(reponse,"fermeture_session" );
  87.     if(comparaison==0)
  88.     {
  89.         system("shutdown -l" );
  90.     }
  91.     lg=strlen(reponse);
  92.     /* envoyer une requete sur la socket "client" */
  93.     send(client,reponse,lg,0);
  94. }


-------------------------------------------------------
 
Voila
si quelqu'un a une petite piste ou une solution a me proposé je vous en
serait très reconnaissant. Je débute en API et je galère un peu. Merci
d'avance


Message édité par lorenzeb le 26-04-2006 à 14:41:25
Reply

Marsh Posté le 26-04-2006 à 13:53:33   

Reply

Marsh Posté le 26-04-2006 à 13:56:06    

- Utilises les balises code, sinon ca rend le reste illisible.
- while(1) c'est très mal. J'ai failli perdre un oeil, pire que le manque de balises.


Message édité par _darkalt3_ le 26-04-2006 à 13:56:42
Reply

Marsh Posté le 26-04-2006 à 13:58:40    

j'oublie:
- précise la manière dont ca plante (message d'erreur ? gel ? ...) stp.
- As tu passé le debugger ? A part constater que ca plantait, qu'as tu entrepris pour régler le souci ?

Reply

Marsh Posté le 26-04-2006 à 14:39:13    

ah oui désolé pour le code. Alors en fait cela me génère un freeze total du programme. En fait je pense changer effectivement mon while(1) et j'ai également vu que la fonction GetMessage dans mon "tant que" du WinMain pouvait etre changer par un PeekMessage. Car apparemment GetMessage serait une fonction bloquante alors que PeekMessage non. Non je n'ai pas encore eu le temps de passer le débugger. Je m'y met de suite.

Reply

Marsh Posté le 26-04-2006 à 21:35:39    

Merci pour tes réponses. Je suis en train de tout revoir et je posterai dès que j'aurai du nouveau. A plus

Reply

Marsh Posté le 27-04-2006 à 16:15:57    

Bonjour à tous,
 
Voila j'ai revu mon code. J'ai donc créer une application réseau (graphique) qui créer une socket et qui se met en écoute en attente d'une connexion.
 
Mon probleme est que lorsque je clique sur mon bouton pour que l'appli se mette en écoute, la fenetre se fige et ensuite plante.  Le problème vient du fait que j'ai une boucle pour actualiser l'affichage dans "WinMain" ce qui est logique, et une autre qui permet au prog d'etre en écoute (dans la procedure "create_connexion" ). Donc lorsque le prog se met en écoute il se bloque dans la boucle d'ecoute et l'affichage ne se fait plus et tout plante.
J'ai entendu vaguement parler des "thread" d'ou le ? dans le titre du sujet mais je ne sais pas du tout m'en servir et je ne suis pas sur non plus que cela règle mon problème.
 
Si quelqu'un a une idée... Merci d'avance et désolé pour le roman :)
 
 
Voila mon code:
 

Code :
  1. /****************BOUCLE PRINCIPALE**************************/
  2. int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow){
  3.         MSG msg; //récupère les messages de windows
  4.         //crée la fenetre
  5.         hwnd = CreateWnd(hInstance);
  6.         ShowWindow (hwnd, iCmdShow);
  7.         //crée un bouton Connexion
  8.         hBoutonConnect = CreateWindow("button", "Lancer", WS_CHILD | WS_BORDER, 95, 30, 90, 20, hwnd, 0, hInstance, 0);
  9.         ShowWindow(hBoutonConnect, iCmdShow);
  10.         //crée un bouton Quitter
  11.         hBoutonQuit = CreateWindow("button", "Quitter", WS_CHILD | WS_BORDER, 10, 60, 175, 20, hwnd, 0, hInstance, 0);
  12.         ShowWindow(hBoutonQuit, iCmdShow);
  13.         //raffraichit la fenetre
  14.         UpdateWindow (hwnd);
  15.    
  16.     //---------Boucle d'affichage---------------------
  17.      while (GetMessage (&msg, NULL, 0, 0)){
  18.           TranslateMessage (&msg);
  19.           DispatchMessage (&msg);
  20.      }
  21.      return msg.wParam;
  22. }
  23. /************FIN DE LA BOUCLE PRINCIPALE*****************/
  24. /******************CREATION DE LA FENETRE*******************/
  25. HWND CreateWnd(HINSTANCE hInst){
  26. code ........
  27. }
  28. /***************FIN CREATION DE LA FENETRE*****************/
  29. /*********************CLIENT***************************/
  30. void create_connexion(){
  31.     int port=0,erreur;
  32.     WSADATA wsa;
  33.     /* initialisation */
  34.     WSAStartup(MAKEWORD(2,0), &wsa);
  35.      
  36.         //variables pour la connexion réseau
  37.         SOCKET serveur;
  38.         SOCKET client;
  39.         SOCKADDR_IN sin;
  40.         SOCKADDR_IN clientsin;
  41.     /* creation de la socket serveur */
  42.     serveur  = socket(AF_INET,SOCK_STREAM,0);
  43.     if(serveur == INVALID_SOCKET){
  44.         MessageBox (NULL, "Impossible de créer la socket", "Client", MB_OK | MB_ICONEXCLAMATION);
  45.         exit(-1);
  46.     }
  47.     /* configuration de la socket */
  48.     sin.sin_addr.s_addr = INADDR_ANY;
  49.     sin.sin_family = AF_INET;
  50.     sin.sin_port = htons(port);
  51.     /* attacher le socket au n° de port*/
  52.     erreur=bind(serveur,(SOCKADDR *)&sin, sizeof(sin));
  53.     if(erreur == INVALID_SOCKET){
  54.         MessageBox (NULL, "Impossible d'ouvrir le port", "Client", MB_OK | MB_ICONEXCLAMATION);
  55.         exit(-1);
  56.     }
  57.     /* creation d'une file d'attente de demande de connexion */
  58.     listen(serveur,0);
  59.     MessageBox (NULL, "Client en écoute", "Client", MB_OK | MB_ICONEXCLAMATION);
  60.         int val = sizeof(clientsin);
  61.         //---------Boucle d'écoute---------------------
  62.         while (client = accept(serveur,(SOCKADDR *)&clientsin,&val)){
  63.      
  64.             /* accepter une connexion */ 
  65.             if(client == INVALID_SOCKET)
  66.                 MessageBox (NULL, "Erreur de connexion", "Client", MB_OK | MB_ICONEXCLAMATION);
  67.             else
  68.                 MessageBox (NULL, "Serveur connecter", "Client", MB_OK | MB_ICONEXCLAMATION);
  69.                 /* fonction qui utilise la socket */
  70.                 traitement(client);
  71.         }
  72. }
  73. /*********************FIN CLIENT*************************/
  74. /*********************TRAITEMENT**********************/
  75. void traitement(SOCKET client){
  76.     code .......
  77. }
  78. /*********************FIN DU TRAITEMENT*******************/
  79. /************************************************************/
  80. /****CONTROLE DES RETOURS DE MESSAGES DE WINDOWS*****/
  81. LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam){
  82.          code .............
  83. }
  84. /***FIN DU CONTROLE DES RETOURS DE MESSAGES DE WINDOWS****/
  85. /************************************************************/


Message édité par lorenzeb le 27-04-2006 à 16:17:06
Reply

Marsh Posté le 27-04-2006 à 16:28:17    

ben si voilà, tu crée un thread d'écoute, et par exemple tu envoies des msg windows évenement quand tu reçois tel ou tel message.
 
Et ça évitera un while(1) ou un truc sale du genre ...

Reply

Marsh Posté le 28-04-2006 à 04:15:54    

ben c'est bon mec merci de ta reponse j'ai créer un thread et ca marche nikel. Merki encore. Salut

Reply

Marsh Posté le 28-04-2006 à 04:16:36    

Edit: voir la fonction CreateThread sur google pour ceux qui ne savent pas. Tcho bonne nuit :)

Reply

Marsh Posté le 28-04-2006 à 08:52:27    

:jap:


---------------
Töp of the plöp
Reply

Sujets relatifs:

Leave a Replay

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