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 :

[BCB5] Utilisation de TClientSocket


Sujet :

C++Builder

  1. #1
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut [BCB5] Utilisation de TClientSocket
    Bonjour à tous.
    Je suis en train de faire des petits tests sur les composants Socket. J'ai donc un client assez minimaliste qui se connecte à un serveur tout aussi simple (en local sur le port 1971). L'un et l'autre affichent les traces de ce qu'ils reçoivent sur leur socket.

    Le problème :
    - le serveur reçoit bien la connexion du client (affiche la trace) et lui balance un message d'AR.
    - côte client, dans le gestionnaire OnSocketEvent de la Socket du composant TClientSocket, je reçois (et affiche) les événements :
    seLookup
    seConnecting
    ... et c'est tout.
    Pas de seConnect, a fortiori pas de seRead.

    Qu'ai-je pu oublier, selon vous ?????????

    Oups...
    -

  2. #2
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut,
    poste une partie de ton code pour pouvoir t'aider au mieux
    Cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  3. #3
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    Salut !

    Tu as raison. Je voulais éviter de trop alourdir le message, mais mes explications sont insuffisantes.

    Cela dit, j'ai obtenu des indices sur le forum de Borland, donc le problème est en passe d'être résolu. Pour info, il semblerait que mon problème vienne de ce que j'ai utilisé une socket non bloquante en la plaçant dans un thread à part. Remy Lebeau, du TeamB, me répond ceci :
    You are putting the socket into its own thread and then trying to use the socket in non-blocking mode. That explains why you can't get it to work correctly. Non-blocking sockets use window message internally, which means that the owning thread requires an active message queue. Your thread has no message queue of its own at all, thus the socket can't operation correctly.

    You need to either:
    1) give the thread a message queue so that the socket can process its
    internal notifications
    2) set the socket's ClientType property to ctBlocking instead. That will
    put the socket into blocking mode, in which case window messages are no
    longer used and a message queue is not needed. You will need to use a
    TWinSocketStream to access the socket for reading and writing, though.

    1) give the thread a message queue so that the socket can process its
    internal notifications
    2) set the socket's ClientType property to ctBlocking instead. That will
    put the socket into blocking mode, in which case window messages are no
    longer used and a message queue is not needed. You will need to use a
    TWinSocketStream to access the socket for reading and writing, though.
    Solution en cours de test, mais elle pose d'autres problèmes, comme celle de la gestion des exceptions.
    En effet, j'ai retiré la socket du thread secondaire et je me contente de lire les événements interceptés par les gestionnaires d'événements. Malheureusement, si d'aventure je connecte mon client sur un port que personne n'écoute ou si je déconnecte le serveur après connexion, je reçois un message (une exception apparemment) :

    Erreur socket asynchrone 10061.

    Mais mon gestionnaire OnError sur la socket n'intercepte rien.
    Question : où puis-je intercepter cette erreur ?

    Allez, cette fois, je mets le code
    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
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
     
    [AgentCnxClient.h]
    class FAgentCnxClient
    { ... plein de binious dont un private auto_ptr< TClientSocket > m_pSocket;
    };
     
    [AgentCnxClient.cpp]
    //---------------------------------------------------------------------------
    // -- constructeur --
    // -> public
    // @in parentWnd_P : fenêtre mère
    // @in host_P : nom de l'hôte à contacter
    // @in ip_P : adresse IP de la machine à contacter
    // @in port_P : n° de port du service à contacter
    //---------------------------------------------------------------------------
    FAgentCnxClient::FAgentCnxClient( TFichePrincipale& parentWnd_P,
                                      const string& ip_P,
                                      const string& host_P,
                                      int port_P )
    : m_parentWnd( parentWnd_P )
    {
      m_pSocket.reset( new TClientSocket( NULL ) );
      m_pSocket->Address = ip_P.c_str();
      m_pSocket->Host = host_P.c_str();
      m_pSocket->Port = port_P;
      m_pSocket->ClientType = ctNonBlocking;
     
      m_pSocket->OnError = ClientSocketError;
      m_pSocket->OnRead = ClientSocketRead;
    }
     
     
    //---------------------------------------------------------------------------
    // -- destructeur --
    // -> public
    //---------------------------------------------------------------------------
    FAgentCnxClient::~FAgentCnxClient()
    {
      disconnect();
    }
     
     
    //---------------------------------------------------------------------------
    // -- connect --
    // -> public
    //---------------------------------------------------------------------------
    void FAgentCnxClient::connect()
    {
      if ( m_pSocket.get() == NULL )
      {
        m_parentWnd.displayServerMsg( "Socket non initialisée avant la connexion" );
        return;
      }
     
      try
      {
        m_pSocket->Open();
      }
      catch ( ESocketError& esex )
      {
        m_parentWnd.displayServerMsg( esex.Message );
      }
      catch ( ... )
      {
        m_parentWnd.displayServerMsg(
                    "Erreur non répertoriée dans FClientSocket::connect()" );
      }
    }
     
     
    //---------------------------------------------------------------------------
    // -- disconnect --
    // -> public
    //---------------------------------------------------------------------------
    void FAgentCnxClient::disconnect()
    {
      if ( m_pSocket.get() == NULL )
      {
        m_parentWnd.displayServerMsg( "Socket non initialisée avant la déconnexion" );
        return;
      }
     
      try
      {
        m_pSocket->Close();
      }
      catch ( ESocketError& esex )
      {
        m_parentWnd.displayServerMsg( esex.Message );
      }
      catch ( ... )
      {
        m_parentWnd.displayServerMsg(
                    "Erreur non répertoriée dans FClientSocket::disconnect()" );
      }
    }
     
     
    //---------------------------------------------------------------------------
    // -- ClientSocketError --
    // -> _published
    //---------------------------------------------------------------------------
    void  __fastcall FAgentCnxClient::ClientSocketError( TObject *Sender,
          TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode )
    {
      m_parentWnd.displayServerMsg( "FClientSocket::ClientSocketError" );
    }
     
     
    //---------------------------------------------------------------------------
    // -- ClientSocketRead --
    // -> _published
    //---------------------------------------------------------------------------
    void __fastcall FAgentCnxClient::ClientSocketRead( TObject *Sender,
          TCustomWinSocket *Socket )
    {
      m_parentWnd.displayServerMsg( "FClientSocket::ClientSocketRead" );
      m_parentWnd.displayServerMsg( Socket->ReceiveText() );
    }
     
    [FichePrincipale.cpp] : Initialisation de la connexion
    ...
    m_pAgentCnx.reset( new FAgentCnxClient( *this, strIP, strHost, nPort ) );
    m_pAgentCnx->connect();
    ...
    Voilà. Si vous avez des idées, comme je connais assez mal la programmation C/S, je suis preneur.
    Merci d'avance ! 8)
    Oups...
    -

  4. #4
    Membre chevronné
    Avatar de DjmSoftware
    Homme Profil pro
    Responsable de compte
    Inscrit en
    Mars 2002
    Messages
    1 044
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Suisse

    Informations professionnelles :
    Activité : Responsable de compte
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 044
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    1
    Par défaut
    Salut,
    si tu ne veux pas que ton erreur soit remontée plus haut
    dans ton gestionnaire d'erreur assigne au paramètre ErrorCode la valeur 0 après traitement
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void  __fastcall FAgentCnxClient::ClientSocketError( TObject *Sender, 
          TCustomWinSocket *Socket, TErrorEvent ErrorEvent, int &ErrorCode ) 
    { 
      m_parentWnd.displayServerMsg( "FClientSocket::ClientSocketError" ); 
      ErrorCode =0;
    }
    cordialement
    vous trouverez mes tutoriels à l'adresse suivante: http://djmsoftware.developpez.com/
    je vous en souhaite une excellente lecture ...

    A lire : Les règles du forum

  5. #5
    Nouveau membre du Club
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    31
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Janvier 2003
    Messages : 31
    Points : 29
    Points
    29
    Par défaut
    C'était bien ça !
    Suite des expériences le week end prochain sans doute.
    Et merci pour l'info 8)
    Oups...
    -

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

Discussions similaires

  1. utiliser les tag [MFC] [Win32] [.NET] [C++/CLI]
    Par hiko-seijuro dans le forum Visual C++
    Réponses: 8
    Dernier message: 08/06/2005, 15h57
  2. Réponses: 4
    Dernier message: 05/06/2002, 14h35
  3. utilisation du meta type ANY
    Par Anonymous dans le forum CORBA
    Réponses: 1
    Dernier message: 15/04/2002, 12h36
  4. [BCB5] Utilisation des Ressources (.res)
    Par Vince78 dans le forum C++Builder
    Réponses: 2
    Dernier message: 04/04/2002, 16h01
  5. Réponses: 2
    Dernier message: 20/03/2002, 23h01

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