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 :

Reception de packet UDP


Sujet :

C++Builder

  1. #1
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    24
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 24
    Par d�faut Reception de packet UDP
    Salut,
    J'utilise le composant TUDPSocket pour envoyer et recevoir des packets UDP,
    l'envoi se fait sans probl�me mais la r�ception pose probl�me, Je ne re�ois par les donn�es pourtant elle sont bien pr�sente sur le r�seau.
    Voici mon code
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    void __fastcall TForm1::UdpSocket1Receive(TObject *Sender, PChar Buf,
          int &DataLen)
    {
          AnsiString Trame;
           UdpSocket1->ReceiveBuf(Trame,UdpSocket1->BytesReceived,1);
          Memo1->Text=IntToStr(Trame.Length());//Affichage de la longueur des donnés
          Memo3->Lines->Add("Donnée recues "+Trame);//Affichage datas
    }
    �a � l'air tout con et pourtant je bute dessus donc j'implore votre aide lol
    Merci d'avance
    cordialement.

  2. #2
    Membre Expert
    Avatar de Crayon
    Inscrit en
    Avril 2005
    Messages
    1 811
    D�tails du profil
    Informations personnelles :
    Localisation : Autre

    Informations forums :
    Inscription : Avril 2005
    Messages : 1 811
    Par d�faut
    Salut taquilla, j'ai trouv� du code qui pourrais peut-�tre t'aider, alors le voici:

    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
    BYTE buffer[4096];
     
    Memo1->Clear();
    UdpSocket1->Connect();
    Memo1->Lines->Add(" Local " + String(UdpSocket1->LocalPort) + " Remote " + String(UdpSocket1->RemotePort));
    //...
    int NumRead = UdpSocket1->ReceiveBuf(buffer, sizeof(buffer), 0);
    if( NumRead >= sizeof(DataHeader) )
    {
        DataHeader *pHdr = (DataHeader*)buffer;
     
        Memo1->Lines->Add(String(5000+pHdr->sender)+" "+
            String(pHdr->msgId)+" "+String(pHdr->msgLen)+" "+
            String(NumRead-sizeof(DataHeader)));
    }
    PS: J'ai pas test�

  3. #3
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    24
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 24
    Par d�faut
    Merci de ta r�ponse
    mais malheureusement il ne fonctionne pas
    A+

  4. #4
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    24
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 24
    Par d�faut
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
     
    void __fastcall TForm1::UdpSocket1Receive(TObject *Sender, PChar Buf,
          int &DataLen)
    {
     
     
     
    }
    En r�alit� il n'y a pas d'�v�nement qui arrive, donc la routine ne peut pas s'ex�cuter.
    Par contre pour l'envoi, il y a bien un �v�nement qui est envoy� .
    J'ai regard� plusieurs exemples sur le net, et ils utilisent plus ou moins la m�me technique et apparemment je suis pas le seul � avoir ce souci .
    A+

  5. #5
    Membre � l'essai
    Profil pro
    Inscrit en
    Avril 2008
    Messages
    6
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2008
    Messages : 6
    Par d�faut
    Bonjour bonjour,
    j'ai exactement le m�me probl�me sous Delphi 7, et je viens de m'inscrire � l'instant pour demander de l'aide, apr�s avoir cherch� autant que je pouvais.

    J'utilise le socket UDP fourni dans Delphi 7.

    C'est exactement pareil : mes trames envoy�es sont bien sur le r�seau, un �v�nement d'envoi est bien activ�, mais pas l'�v�nement de r�ception. Je vais lire avec attention vos r�ponses, en esp�rant une solution !
    (ah pardon : je vois que je fais remonter une ancienne discussion, qui date de l'ann�e derni�re ; d�sol�)

  6. #6
    Membre averti
    Inscrit en
    Juillet 2007
    Messages
    24
    D�tails du profil
    Informations forums :
    Inscription : Juillet 2007
    Messages : 24
    Par d�faut
    Salut,
    non non la discution est bien r�cente, je sais qu'avec delphi ont n'a les m�mes composants, par contre il y a beaucoup plus d'exemples, je me suis bas� dessus pour essayer de r�soudre mon probl�me mais c'est toujours pareil.
    Je te tiens au courant si je trouve quelque chose
    A+

  7. #7
    Candidat au Club
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2012
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 4
    Par d�faut
    salut � vous.
    Apparement, depuis toutes ces ann�es, il n'y a pas eu de solution. TUdpSocket n'arriverait -il pas � r�c�ptionner des trames? C'est quand m�me balot d'�tre coinc� comme ca!

  8. #8
    Membre Expert
    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
    Billets dans le blog
    1
    Par d�faut
    Hello
    ce composant est compl�tement bugg�
    il avait au d�part �t� con�u pour la CLX
    utilise � la place les composants Indy ou ceux de Francois Piette (OverByte)
    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

  9. #9
    Candidat au Club
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2012
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 4
    Par d�faut
    Merci de l'info, comme ca c'est plus clair .

    J'avais regard� les possibilit�s de Indy, effectivement ca marche mieux, mais on est oblig� d'utiliser 2 objets Server & Client si on veut Lire & �crire.

    Enfin, tant qu'on utilise l'objet tel quel dans une fiche ca va, mon probl�me c'est que je veux l'utiliser dans une classe de ma DLL, et l� ca se complique!
    Je n'arrive pas a instancier TIdUDPClient comme membre de ma classe, le compilo m'insulte par rapport � certains membres de classe parente de TIdUDPClient !!!

    Si tu as une id�e l� dessus je suis preneur.
    Merki

  10. #10
    Membre Expert
    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
    Billets dans le blog
    1
    Par d�faut
    Salut
    Essaye les composants de Fran�ois Piette (Overbyte) http://www.overbyte.be/frame_index.html
    pour inserer une Form dans une DLL sur laquellle tes composants seront d�pos�s http://bcbjournal.org/articles/vol2/...m_in_a_DLL.htm

    ou alors utilise simplement les API de MS tu devrais trouver des exemples sur le Net

    cdlt
    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

  11. #11
    Membre exp�riment�
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2012
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 164
    Par d�faut
    On aura beau me dire qu'il est inutile de r�inventer la roue, mais il reste que quand on veut faire de la programmation de bas niveau, on est jamais mieux servi que par soi-m�me.Les primitives sont l�, faut juste les adapter � ses besoins.

    Je me suis lanc� r�cemment en programmation Java/Andoid et je me suis �crit un "TUdpSocket" qui contient l'essentiel, soit un "Send" pour la transmission et l'�quivalent d'un �v�nement "OnReceive" pour la r�ception. J'ai �t� �tonn� de voir que c'�tait pas si compliqu�.

    http://guytprog.blogspot.ca/2012/04/...pas-de_14.html

    �videmment, tout est toujours plus compliqu� sous Windows, mais je suis tomb� l�-dessus et quelque chose me dit que la montagne, elle n'est pas si haute, finalement.

    http://www.adp-gmbh.ch/win/misc/sockets.html

  12. #12
    Expert �minent
    Avatar de ShaiLeTroll
    Homme Profil pro
    D�veloppeur C++\Delphi
    Inscrit en
    Juillet 2006
    Messages
    14 089
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    �ge : 44
    Localisation : France, Seine Saint Denis (�le de France)

    Informations professionnelles :
    Activit� : D�veloppeur C++\Delphi
    Secteur : High Tech - �diteur de logiciels

    Informations forums :
    Inscription : Juillet 2006
    Messages : 14 089
    Par d�faut
    Par d�faut le composant est en BlockMode bmBlocking et ne re�oit pas l'�v�nement OnReceive !

    Il faut cr�er un thread qui lit en boucle le TWinSocketStream
    On attend la pr�sence de donn�e avec WaitForData puis on lit avec Read\ReadBuffer

    Pour activer OnReceive, il faut passer BlockMode � bmNonBlocking !

    Personne ne l'a mentionn�, c'est peut-�tre trivial et j'esp�re que cela a d�j� �t� test� !
    Mais parfois, c'est les trucs de bases qui coincent !

    Sinon, � partir de Delphi 7, il faut effectivement utiliser les composants Indy
    Cela fait 10 ans que TClientSocket, TServerSocket et TUdpSocket sont d�clar�s obsol�tes pourtant ils ont �t� migr� en XE2 et sont toujours maintenus !
    Aide via F1 - FAQ - Guide du d�veloppeur Delphi devant un probl�me - Pensez-y !
    Attention Troll M�chant !
    "Quand un homme a faim, mieux vaut lui apprendre � p�cher que de lui donner un poisson" Confucius
    Mieux vaut se taire et para�tre idiot, Que l'ouvrir et de le confirmer !
    L'ignorance n'excuse pas la m�diocrit� !

    L'exp�rience, c'est le nom que chacun donne � ses erreurs. (Oscar Wilde)
    Il faut avoir le courage de se tromper et d'apprendre de ses erreurs

  13. #13
    Candidat au Club
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2012
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 4
    Par d�faut
    Bonjour,

    D'accord avec toi Guyt54. Faut juste adatper. D'ailleur merci pour ton forum sur lequel j'�tais tomb� (aie) et dont je m'�tais inspir�.

    Merci aux autres pour vos pr�cisions, j'ai mati�re � r�fl�chir maintenant.
    Y a plus qu'�, surtout cot� Thread ?!? Mais pas tout saisi :puisqu'il y aurait un thread qui scrute si y a quelques choses � lire, pourquoi waitfordata?

    Je vous tiens au courant de ma solution trouv� qu'on ferme ce topic une bonne fois pour toute ! ;-)

    Bonne journ�e

  14. #14
    Membre exp�riment�
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2012
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 164
    Par d�faut
    en tout cas, festinno, il est motivant, ton post.

    je travaille depuis hier � l'�criture d'un UDP socket, comme je m'en doutais, c'est pas �vident.

    L�, je viens de tomber l�-dessus:

    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    Tu regarderas l'exemple, pour une fois que Microsoft nous en donne un pas mal.

  15. #15
    Membre exp�riment�
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2012
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 164
    Par d�faut
    YES!!!!!!!!!!!!!!!!


    J'ai adapt� l'exemple de microsoft. c'est tr�s lourd pour l'instant, mais la transmission UDP fonctionne, �a nous donne une bonne base de travail pour faire du code plus intelligent.
    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
     
    AnsiString UdpSend(AnsiString data, AnsiString ipAddr, int port)
    // http://msdn.microsoft.com/en-us/library/windows/desktop/ms737625%28v=vs.85%29.aspx
    {
        AnsiString mes ;
        int iResult ;
     
        // Initialize Winsock
        WSADATA wsaData;
        iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (iResult != NO_ERROR)
        {
            mes.sprintf("WSAStartup function failed with error: %d",iResult) ;
            return mes ;
        }
     
        // Create a SOCKET for connecting to server
        SOCKET ConnectSocket;
        ConnectSocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
        if (ConnectSocket == INVALID_SOCKET)
        {
            mes.sprintf("socket function failed with error: %ld", WSAGetLastError());
            WSACleanup();
            return mes ;
        }
     
        // The sockaddr_in structure specifies the address family,
        // IP address, and port of the server to be connected to.
        sockaddr_in clientService;
        clientService.sin_family = AF_INET;
        clientService.sin_addr.s_addr = inet_addr(ipAddr.c_str());
        clientService.sin_port = htons(port);
     
         // Connect to server.
        iResult = connect(ConnectSocket, (SOCKADDR *) & clientService, sizeof (clientService));
        if (iResult == SOCKET_ERROR)
        {
            mes.printf("connect function failed with error: %ld", WSAGetLastError());
            closesocket(ConnectSocket);
            WSACleanup();
            return mes ;
        }
        // Send data
         send(ConnectSocket,data.c_str(),data.Length(),0) ;
         ShowMessage("data transmitted") ;
        // Close
        closesocket(ConnectSocket);
        WSACleanup();
        return "DONE!!!" ;
    }
    Je regarde c�t� r�ception, maintenant.

    C'est vraiment mon jour de chance:

    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    et aussi:
    http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

    finalement:
    http://www.win32developer.com/tutori...utorial_3.shtm

  16. #16
    Membre exp�riment�
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2012
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 164
    Par d�faut
    Bon, le UDP en r�ception fonctionne (mode non-blocking).

    Encore une fois, du code adapt� � partir d'un exemple de Microsoft:

    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
     
    AnsiString UdpGet(int listenPort,AnsiString& rxData, AnsiString& ipAddr, int& port)
    // recvfrom failed with error 10035
    {
        AnsiString mes ;
        int iResult ;
     
        // Initialize Winsock
        WSADATA wsaData;
        iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
        if (iResult != NO_ERROR)
        {
            mes.sprintf("WSAStartup function failed with error: %d",iResult) ;
            return mes ;
        }
     
        // Create a receiver socket to receive datagrams
        SOCKET RecvSocket ;
        RecvSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
        if (RecvSocket == INVALID_SOCKET)
        {
           mes.sprintf("socket function failed with error: %ld", WSAGetLastError());
           WSACleanup();
           return mes ;
        }
        // Set to non-blocking mode
    	   u_long iMode=1;   // If iMode!=0, non-blocking mode is enabled.
    	   ioctlsocket(RecvSocket,FIONBIO,&iMode);
     
        // Bind the socket to any address and the specified port.
        sockaddr_in RecvAddr;
        RecvAddr.sin_family = AF_INET;
        RecvAddr.sin_port = htons(listenPort);
        RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
        iResult = bind(RecvSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr));
        if (iResult != NO_ERROR)
        {
            mes.printf("bind failed with error %d\n", WSAGetLastError());
            closesocket(RecvSocket);
            WSACleanup();
            return mes ;
        }
       // Ready to read data
       char RecvBuf[256] ;
       int  BufLen = 255 ;
       int  DataCount ;
       sockaddr_in SenderAddr;
       int SenderAddrSize = sizeof(SenderAddr) ;
       // tell user to send data in modal ok dialog
       ShowMessage("Ready to receive data, press ok when data transmitted (or not!)") ;
       // read data
       int retries = 0 ;
       do
       {
         DataCount = recvfrom(RecvSocket,RecvBuf, BufLen, 0,
                             (SOCKADDR*)&SenderAddr, &SenderAddrSize);
         retries++  ;
         Sleep(1000) ;
       }
       while (DataCount < 0  && retries < 5) ;
       if (DataCount > 0)  // -1  if error
       {
         RecvBuf[DataCount] = 0 ;
         rxData = AnsiString(RecvBuf) ;
         mes = "OK" ;
       }
       else
       {
         mes.sprintf("recvfrom failed with error %d", WSAGetLastError()) ;
       }
       // Close
       closesocket(RecvSocket);
       WSACleanup();
       return mes ;
    }
    Reste plus qu'� int�grer tout �a dans un composant facile d'utilisation, la roue aura �t� r�invent�e, mais le UDP d�mystifi�.

  17. #17
    Candidat au Club
    Homme Profil pro
    Ing�nieur d�veloppement logiciels
    Inscrit en
    Mai 2012
    Messages
    4
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activit� : Ing�nieur d�veloppement logiciels

    Informations forums :
    Inscription : Mai 2012
    Messages : 4
    Par d�faut
    Salut,

    pas si lourd que ca le code � int�grer, assez facile de compr�hension une fois qu'on l'a sous les yeux, mais ce n'est pas une d�marche que j'aurai invent�.

    Merci pour les explications et les liens associ�s (aussi important).

    Pour ma part, l'envoi UDP fonctionne aussi tr�s bien avec winsock, comme j'avais pu le faire en utilisant une instance de TUDPSocket.

    Par contre j'ai quelques soucis encore avec la r�ception de donn�es...
    affaire � suivre...

    En tout cas merci pour les exemples Guyt54 et MS un peu aussi. ;-)

  18. #18
    Membre exp�riment�
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2012
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 164
    Par d�faut
    Et voil�, la transmission/r�ception UDP en un seul composant que j'ai appel� "TUdpSockit" comme dans "Sock it to me".

    Une propri�t� r�ellement importante, "ListenPort" pour le port de r�ception.

    Deux m�thodes pour la la transmission (Send et SendString)

    Deux �v�nements (exclusif) pour la r�ception "OnRxUdpData" et "OnRxUdpString".

    UdpSockit.h:

    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
     
    // UdpSocket.h
     
    #ifndef UdpSockitH
    #define UdpSockitH
     
    #include <SysUtils.hpp>
    #include <Classes.hpp>
    #include <WinSock2.h>
     
    typedef void __fastcall (__closure *TRxUdpDataEvent)(TObject* Sender,
                                                         void* dest,
                                                         int count,
                                                         AnsiString fromIP,
                                                         int fromPort) ;
     
    typedef void __fastcall (__closure *TRxUdpStringEvent)(TObject* Sender,
                                                           AnsiString data,
                                                           AnsiString fromIP,
                                                           int fromPort);
     
    class PACKAGE TUdpSockit : public TComponent
    {
     
      public:
       // Constructeur et destructeur
     
      __fastcall TUdpSockit(TComponent* owner) ;
    	 virtual _fastcall ~TUdpSockit(void) ;
      bool Send(AnsiString ipAddr, int port, const void* data, int count) ;
      bool SendString(AnsiString ipAddr, int port, AnsiString stg) ;
      AnsiString GetErrorMes(void) ;
     
      private:
      AnsiString fErrorMes ;
      bool fDllLoaded ;
      TRxUdpDataEvent fOnRxUdpData ;
      TRxUdpStringEvent fOnRxUdpString ;
     
      // Gestion réception
      SOCKET fRxSocket ;
      sockaddr_in fSenderAddr;
      int fSenderAddrSize ;
      int fListenPort ;
      char* fRxBuf ;
      int   fRxBufSize ;
      int   fRxCount ;
     
      bool InEditMode(void) ;
      void DisableReceptionHandling(void) ;
      void ResetReceptionHandling(void) ;
      bool EnableReceiveSocket(void) ;
      bool ReadRxSocket(void) ;
     
      	// Gestion Timer
      int fTimerID ;
    	 int fPollingInterval ; // in millisec
      static void __stdcall TimerCallBackProc(UINT uTimerID, UINT uMessage, ULONG dwUser,
    												                            		ULONG dw1, ULONG dw2) ;
       void TimerHandler(void) ;
     
      // Gestion propriétés
      void __fastcall SetPollingInterval(int val) ;
      void __fastcall SetListenPort(int val) ;
      void __fastcall SetRxBufSize(int val) ;
      void __fastcall SetOnRxUdpData(TRxUdpDataEvent event) ;
      void __fastcall SetOnRxUdpString(TRxUdpStringEvent event) ;
     
      __published:
      __property int PollingInterval = {read=fPollingInterval,
                                        write=SetPollingInterval, default=50 } ;
     
      __property int ListenPort = {read=fListenPort, write=SetListenPort, default=1954 } ;
      __property int RxBufSize = {read=fRxBufSize, write=SetRxBufSize, default=1024} ;
      __property TRxUdpDataEvent OnRxUdpData = { read=fOnRxUdpData, write=SetOnRxUdpData } ;
      __property TRxUdpStringEvent OnRxUdpString = { read=fOnRxUdpString,
                                                      write=SetOnRxUdpString} ;
     
      protected:
      void virtual __fastcall Loaded(void) ;
    };
    #endif
    UdpSockit.cpp:
    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
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
     
    /*
    ================================================================================
    Composant TUdpSockit (Sock it to me)
    Guy Tessier, mai 2012
     
    librairie Windows requise: ws2_32.lib
    Réception/Transmission internet protocole UDP
     
    Propriétés:
    ----------
     
    ListenPort:      Port utilisé pour la réception
    PollingInterval: Intervalle du timer interne utilisé pour la réception
                      en milliseconde (défaut: 50ms, précision 1 ms)
    RxBufSize:       Grosseur maximum des paquets UDP (défaut= 1024)
     
    Méthodes:
    --------
     
    bool SendString(AnsiString ipAddr, int port, AnsiString stg) ;
    bool Send(AnsiString ipAddr, int port, const void* data, int count) ;
     
    Transmission de chaine ou de données brutes à l'adresse et au port UDP
    précisé. Indique si réussi. Si erreur on aura plus de détail en appelant
    la méthode "GetErrorMes"
     
    Événements (sur réception):
    --------------------------
     
    // L'un ou l'autre (mais pas les deux!)
    void __fastcall fUdpSocketRxUdpString(TObject *Sender, AnsiString data,
                                          AnsiString fromIP, int fromPort)
     
    void __fastcall fUdpSocketRxUdpData(TObject *Sender, void *dest, int count,
                                        AnsiString fromIP, int fromPort)
    Un message à l'écran apparaitra en cas d'erreur de connexion avec soncket
    interne.
    ================================================================================
    */
     
    #pragma hdrstop
     
    #include "UdpSockit.h"
    #include <dialogs.hpp>
     
    #pragma package(smart_init)
     
    static inline void ValidCtrCheck(TUdpSockit *)
    {
     new TUdpSockit(NULL);
    }
    namespace Udpsockit
    {
      void __fastcall PACKAGE Register()
      {
        TComponentClass classes[1] = {__classid(TUdpSockit)};
        RegisterComponents("Guyt", classes, 0);
      }
    }
     
    // ========
    // Messages
    // ========
     
    const AnsiString  MES_RX_SOCKET_ERR = "Erreur critique lors de l'initialisation"
                                          " du socket de réception UDP" ;
    const AnsiString  MES_TX_SOCKET_ERR = "Erreur de création socket de transmission" ;
    const AnsiString  MES_LOAD_DLL_ERR = "Erreur WinSock DLL" ;
    const AnsiString  MES_TX_CONNECT_ERR = "Erreur connexion socket transmission" ;
     
    // ===========================
    // Constructeur et destructeur
    // ===========================
     
     __fastcall TUdpSockit::TUdpSockit(TComponent* owner) : TComponent(owner)
     {
        WSADATA wsaData;
        fDllLoaded = WSAStartup(MAKEWORD(2, 2), &wsaData) == NO_ERROR ;
        fPollingInterval = 50 ;
        fListenPort = 1954;
        fRxBufSize = 1024 ;
        fSenderAddrSize = sizeof(sockaddr_in) ;
        fOnRxUdpString = NULL ;
     }
     
     _fastcall TUdpSockit::~TUdpSockit(void)
     {
       DisableReceptionHandling() ;
       if (fDllLoaded)
          WSACleanup();
     }
     
    void __fastcall  TUdpSockit::Loaded(void)
    // Appelé au lancement de l'application
    // Les proriétés et événements ont été intialisées
     
     
    {
       TComponent::Loaded() ;
       if (!InEditMode())
            ResetReceptionHandling() ;
    }
     
     // ==================
     // Méthodes publiques
     // ==================
     
     AnsiString TUdpSockit::GetErrorMes(void)
     {
       return fErrorMes ;
     }
     
     bool TUdpSockit::Send(AnsiString ipAddr, int port, const void* data, int count)
     {
         // Vérifier si DLL installé
         if (!fDllLoaded)
         {
           fErrorMes = MES_LOAD_DLL_ERR ;
           return false ;
         }
     
         // Créer un socket
         SOCKET txSocket;
         txSocket = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
         if (txSocket==INVALID_SOCKET)
         {
           fErrorMes = MES_TX_SOCKET_ERR ;
           return false ;
         }
     
         // Spécifier l'adresse du destinataire
        sockaddr_in clientService;
        clientService.sin_family = AF_INET;
        clientService.sin_addr.s_addr = inet_addr(ipAddr.c_str());
        clientService.sin_port = htons(port);
     
        // connexion au serveur
        if( connect(txSocket, (SOCKADDR *) & clientService,
                     sizeof (clientService)) == SOCKET_ERROR)
        {
          fErrorMes = MES_TX_CONNECT_ERR ;
          return false ;
        }
     
       // Transmet données (blocking mode)
       send(txSocket,(const char*)data,count,0) ;
     
       // ferme socket
       closesocket(txSocket);
       return true ;
    }
     
    bool TUdpSockit::SendString(AnsiString ipAddr, int port, AnsiString stg)
    {
      return Send(ipAddr,port,stg.c_str(),stg.Length()) ;
    }
     
    // ================
    // Méthodes privées
    // ================
     
    // -----------------
    // Gestion réception
    // -----------------
     
    bool TUdpSockit::InEditMode(void)
    {
       return ComponentState.Contains(csDesigning) ;
    }
     
     
    void TUdpSockit::DisableReceptionHandling(void)
    {
      if (fTimerID)
       {
         timeKillEvent(fTimerID);
         fTimerID = NULL ;
       }
      if (fRxSocket)
      {
         closesocket(fRxSocket);
         fRxSocket = NULL ;
      }
      if (fRxBuf)
      {
         delete []fRxBuf ;
         fRxBuf = NULL ;
      }
    }
     
    void TUdpSockit::ResetReceptionHandling(void)
    {
      bool isRequired ;
     
      DisableReceptionHandling() ; // on fait le grs ménage
      isRequired = (fOnRxUdpString || fOnRxUdpData) ;
      if (isRequired)
      {
        if (EnableReceiveSocket())
        {
          fRxBuf = new char[fRxBufSize+1] ; // + 1 pour un NULL éventuel
          fTimerID = timeSetEvent(fPollingInterval, 0, TimerCallBackProc, (
                                  ULONG)this, TIME_PERIODIC);
        }
        else
        {
           ShowMessage(MES_RX_SOCKET_ERR) ;
        }
      }
    }
     
    bool TUdpSockit::EnableReceiveSocket(void)
    {
       bool ok ;
     
       ok = fDllLoaded ;
       if (ok)
       {
         fRxSocket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);
         ok = (fRxSocket != INVALID_SOCKET) ;
         if (ok)
         {
           u_long iMode=1;   // If iMode!=0, non-blocking mode is enabled.
    	      ioctlsocket(fRxSocket,FIONBIO,&iMode);
           // Bind the socket to any address and the specified port.
           sockaddr_in RecvAddr;
           RecvAddr.sin_family = AF_INET;
           RecvAddr.sin_port = htons(fListenPort);
           RecvAddr.sin_addr.s_addr = htonl(INADDR_ANY);
           ok  = bind(fRxSocket, (SOCKADDR *) & RecvAddr, sizeof (RecvAddr)) == NO_ERROR;
           if (!ok)
             closesocket(fRxSocket);
         }
        if (!ok)
          fRxSocket = NULL ;
     
      }
      return ok ;
    }
     
     
    bool TUdpSockit::ReadRxSocket(void)
    // lecture mode non-blocking
    {
      int senderAddrSize ;
      fRxCount = 0 ;
      if (!fRxSocket)
        throw "erreur critique: échec lecture socket" ;
      fRxCount = recvfrom(fRxSocket,fRxBuf,fRxBufSize, 0,
                          (SOCKADDR*)&fSenderAddr, &fSenderAddrSize);
      if (fRxCount < 0) // erreur non-critique ou pas de données
        fRxCount = 0 ;
      return (fRxCount > 0) ;
    }
     
    // -------------
    // Gestion Timer
    // -------------
     
    void __stdcall TUdpSockit::TimerCallBackProc(UINT uTimerID, UINT uMessage,
                                                 ULONG dwUser,
    					                            		          ULONG dw1, ULONG dw2)
    {
      TUdpSockit* This = (TUdpSockit*) dwUser;
      This->TimerHandler();
    }
     
    void TUdpSockit::TimerHandler(void)
    // Validé si événement attaché
    {
      if (ReadRxSocket())
      {
         AnsiString ipAddr = AnsiString(inet_ntoa(fSenderAddr.sin_addr)) ;
         int port = fSenderAddr.sin_port ;
         if (fOnRxUdpString)
         {
            fRxBuf[fRxCount] = 0 ;
            fOnRxUdpString(this,AnsiString(fRxBuf),ipAddr,port) ;
            return ;
         }
         if (fOnRxUdpData) // insécurité
         {
            fOnRxUdpData(this,fRxBuf,fRxCount,ipAddr,port) ;
         }
      }
    }
     
    // ------------------
    // Gestion propriétés
    // ------------------
     
    void __fastcall TUdpSockit::SetPollingInterval(int val)
    {
      fPollingInterval = val ;
      if (!InEditMode())
       ResetReceptionHandling() ;
    }
     
    void __fastcall TUdpSockit::SetListenPort(int val)
     {
       fListenPort = val ;
       if (!InEditMode())
        ResetReceptionHandling() ;
     }
     
    void __fastcall  TUdpSockit::SetRxBufSize(int val)
    {
       fRxBufSize = val ;
       if (!InEditMode())
        ResetReceptionHandling() ;
    }
     
    void __fastcall TUdpSockit::SetOnRxUdpData(TRxUdpDataEvent event)
    {
      fOnRxUdpData = event ;
      if (!InEditMode())
       ResetReceptionHandling() ;
    }
     
    void __fastcall TUdpSockit::SetOnRxUdpString(TRxUdpStringEvent event)
    {
      fOnRxUdpString = event ;
      if (!InEditMode())
       ResetReceptionHandling() ;
    }

  19. #19
    Membre Expert
    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
    Billets dans le blog
    1
    Par d�faut
    Hello
    Beau Travail Guyt
    malheureusement ne fonctione pas � partir de XP
    les Fonctions timeKillEvent et timeSetEvent de la library Winmm.lib.
    sont comme tu peux le lire
    Windows XP: Included in Windows XP only.
    Header: Declared in Mmsystem.h; include Windows.h.
    Library: Use Winmm.lib.

    cdlt
    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

  20. #20
    Membre exp�riment�
    Homme Profil pro
    Enseignant
    Inscrit en
    Mars 2012
    Messages
    164
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activit� : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Mars 2012
    Messages : 164
    Par d�faut
    Citation Envoy� par DjmSoftware Voir le message
    Hello
    Beau Travail Guyt
    malheureusement ne fonctione pas � partir de XP
    les Fonctions timeKillEvent et timeSetEvent de la library Winmm.lib.
    sont comme tu peux le lire
    Windows XP: Included in Windows XP only.
    Header: Declared in Mmsystem.h; include Windows.h.
    Library: Use Winmm.lib.

    cdlt
    �a me surprend ce que me dis. les deux fonctions que j'utilise sont les m�mes que celles de mon timer (MMTimer) et que j'ai d�velopp� sous XP.

    je vais regarder �a de plus pr�s.

    �dition #1:

    Reste � v�rifier le fonctionnement, mais �a passe tel quel au niveau de la compilation et de l�installation du paquet (bpl) en XP avec Codegear 2009.

    faut pas oublier d'inclure ws2_32.lib dans le package

Discussions similaires

  1. Comment connaitre la taille d'un packet UDP ?
    Par Djobird dans le forum Entr�e/Sortie
    R�ponses: 2
    Dernier message: 16/07/2009, 16h58
  2. probleme de reception de message udp apres envoi
    Par zarbiman dans le forum D�veloppement
    R�ponses: 2
    Dernier message: 12/12/2007, 23h21
  3. Probl�me de packet UDP avec les routeurs
    Par Thixomag dans le forum D�veloppement
    R�ponses: 16
    Dernier message: 11/11/2007, 20h38
  4. Checksum d'un packet udp
    Par sebastien.mz dans le forum R�seau
    R�ponses: 3
    Dernier message: 12/05/2007, 15h00
  5. r�cup�rer la taille d'un packet UDP
    Par beLz dans le forum R�seau
    R�ponses: 17
    Dernier message: 07/03/2007, 11h50

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