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++Builder Discussion :

Programme figer ? comment y remédier


Sujet :

C++Builder

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut Programme figer ? comment y remédier
    Bonjour,

    Mon programme initialise un socket demystifié côté serveur jusque là pas de problème et au moment où il dois attendre une connexion client il devient tout blanc, il se fige. Mais dès que le client se connecte paf il est plus figer. Donc mon but serai qu'il ne se fige pas pour que l'on puisse fermer la fenetre à tout moment sans passer par le gestionnaire des tâches. Faut-il faire un thread sinon voilà le bout de code qui fige mon programme :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    int sinsize = sizeof(csin);
    csock = accept(sock, (SOCKADDR *)&csin, &sinsize);
    Pour info: sock est le socket

  2. #2
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut
    Je crois que j'ai trouvé:
    http://c.developpez.com/faq/bcb/?pag...plicationfigee
    mais il faut que je vérifie et je vous redit. Et si vous avez des meilleurs idées pour mon cas faites en part

    EDIT: Cette solution ne peux pas marcher dans mon cas car c'est une seule commande qui fait figer mon application pas une boucle... Si vous pouvez me répondre svp

  3. #3
    Membre averti
    Avatar de Neo41
    Inscrit en
    Janvier 2003
    Messages
    241
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 241
    Points : 403
    Points
    403
    Par défaut
    Bonjour,

    effectievement dans ton cas, Application->ProcessMessages ne te sert à rien et ton application va figer quand même pour la simple raison que ce code ne sera jamais atteint !! En fait ce qui fige l'appli est la méthode accept. Cette méthode est bloquante, càd qu'elle ne rend pas la main tant qu'une demande de connexion n'a pas été faite.

    Pour pouvoir gérer les connexions à part il faut faire ca dans un thread (du moins c'est comme ca que je fais). Dans ce thread il faut boucler indéfiniment (while(true)), et dans ce while il faut venir faire un select. Ensuite c'est au retour de ce select que tu peux tester s'il y a une demande de connexion, des données qui attendent d'être lues, etc.

    Si t'es novice avec les sockets je te conseille de commencer par te documenter là dessus, surtout le select.

    Bon courage

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut
    Merci pour ta réponse d'ailleurs la seule, j'ai cru je j'allais pas avoir de réponse. C'est vrai tu me rappelle que la fonction accept est bloquante et pour y remédier il faut utiliser un thread avec une boucle while(1) avec select,

    aurait tu une doc desssus stp ? car je connais pas, je suis un peu novice en bcb, mais je commence à bien comprendre les sockets.

  5. #5
    Membre averti
    Avatar de Neo41
    Inscrit en
    Janvier 2003
    Messages
    241
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 241
    Points : 403
    Points
    403
    Par défaut
    Bonjour,

    voici le code complet d'une simple application console qui fait serveur TCP. Le serveur se contente d'envoyer une trame au client, mais bien évidemment tu peux faire le traitement que tu veux:

    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
     
    //---------------------------------------------------------------------------
     
    #include <iostream>
     
    #include <stdio.h>
    #include <conio.h>
     
    using namespace std;
     
    #pragma hdrstop
     
    //---------------------------------------------------------------------------
     
    #pragma argsused
     
    DWORD WINAPI ServerThread(LPVOID pParam);
     
    int main(int argc, char* argv[])
    {
      DWORD ThId = 0;
     
      cout << "Appuyer qur Esc pour quitter\r\n";
      CreateThread(NULL, 0, ServerThread, 0, 0, &ThId);
      while(getch()!=27);
     
      return 0;
    }
    //---------------------------------------------------------------------------
     
    DWORD WINAPI ServerThread(LPVOID pParam)
    {
        cout << "Serveur TCP lancé\r\n";
        SOCKET server;
        SOCKET client;
        sockaddr_in from;
        WSADATA wsaData;
        sockaddr_in local;
     
        //Initialisation socket
        int wsaret=WSAStartup(0x101,&wsaData);
     
        if(wsaret!=0)
        {
            cout << "Mauvaise version socket\r\n";
            return 0;
        }
     
        //Paramètres du serveur
        local.sin_family=AF_INET; //TCP
        local.sin_addr.s_addr=INADDR_ANY; //Adresse IP aléatoire
        local.sin_port=htons((u_short)10000); //Port d'écoute
     
        //création du socket serveur
        server=socket(AF_INET,SOCK_STREAM,0);
     
        if(server==INVALID_SOCKET)
        {
            cout << "Impossible de créer un socket\r\n";
            return 0;
        }
     
        //Association @IP<->Port
        if(bind(server,(sockaddr*)&local,sizeof(local))!=0)
        {
          cout << "Erreur Bind\r\n";
          return 0;
        }
     
        //début d'écoute
        if(listen(server,10)!=0)
        {
          cout << "Erreur Listen\r\n";
          return 0;
        }
     
        int fromlen=sizeof(from);
     
        while(true)
        {
          char temp[512];
     
          //Accepter les demandes de connexion
          client=accept(server,
              (struct sockaddr*)&from,&fromlen);
     
          cout << "Connexion de " << inet_ntoa(from.sin_addr) <<"\r\n";
     
          //Envoi d'une trame vers le client
          sprintf(temp,"Votre adresse IP est %s\r\n",inet_ntoa(from.sin_addr));
          send(client,temp,strlen(temp),0);
     
          //Fermeture de la connexion
          closesocket(client);
        }
     
        //Fermeture du serveur
        closesocket(server);
     
        WSACleanup();
     
        return 0;
    }
    J'espère que ca t'aideras.

    Bon courage

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Août 2004
    Messages
    152
    Détails du profil
    Informations personnelles :
    Localisation : Suisse

    Informations forums :
    Inscription : Août 2004
    Messages : 152
    Points : 70
    Points
    70
    Par défaut
    Merci, je vais essayer dès que je le pourrais. une question donc ce thread tourne sans cesse,
    puis je peux envoyer des send avec une action sur un bouton c'est ok j'ai programmer un truc pour ça aucun while necessaire pour ça et par contre dans le thread principal si je met un while(1) pour afficher les messages que je reçois quand j'en reçois il me met n'importe quel caractère alors que le client n'a envoyé aucun message, j'ai dû le mettre en commentaire sinon CPU: 100% :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    while(1)
    {
    char * Recu = new char[256];
     
    recv(sock, Recu, sizeof(Recu),0);
    BoitePrincipale->Lines->Add("Message reçu:");
    BoitePrincipale->Lines->Add(Recu);
    }
    (Ceci ce trouve dans mon thread principal)

    Si je met cet instruction sans le while elle marche correctement 1 fois côté client et côté serveur elle marche pas du tout, les caractères affichés sont rien a voir... . quelqu'un aurait une solution ?

    EDIT: Alors oui, j'ai essayer, et ça règle mon cas et même me permet d'accepter toutes les nouvelles connexions, 1 seul bug, quand ce nouveau thread se lance il accpete une personne qui existe pas, même si c'est pas trop un probème csock != INVALID_SOCKET bloque le send donc pas trop de problème,
    MERCI beaucoup !!!!

  7. #7
    Membre averti
    Avatar de Neo41
    Inscrit en
    Janvier 2003
    Messages
    241
    Détails du profil
    Informations forums :
    Inscription : Janvier 2003
    Messages : 241
    Points : 403
    Points
    403
    Par défaut
    Il faut faire un select pour éviter d'essayer de lire s'il n'y a rien. Tu peux regarder un peu les liens suivants :

    http://www.lowtek.com/sockets/select.html
    http://www.codersource.net/winsock_tutorial_server_select_model.html

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

Discussions similaires

  1. Réponses: 5
    Dernier message: 05/01/2010, 03h16
  2. Réponses: 3
    Dernier message: 11/04/2008, 11h19
  3. Duplication code css, comment y remédier ?
    Par sunshine33 dans le forum Mise en page CSS
    Réponses: 3
    Dernier message: 26/04/2006, 14h53
  4. [HTML] espace indésiré en deux cellule, comment y remédier?
    Par samuelMB dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 07/04/2006, 21h11
  5. erreur C2084 : comment y remédier ?
    Par LMA dans le forum MFC
    Réponses: 12
    Dernier message: 15/03/2006, 09h42

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