CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 8 of 8
  1. #1
    Join Date
    Feb 2009
    Location
    Bretagne, France
    Posts
    5

    [RESOLVED] How can an Asynchronous Socket transmit Data to its owner ?

    Hi,

    I hope I will be able to explain my problem.... let's start :

    I have a class, inherited from CAsyncSocket, called CDiplomat.

    MyDiplomat is a member of the MainWindow class.

    Since MyDiplomat is asynchronous, and threaded, I can't really check every seconds if MyDiplomat has new data, especially because of concurrency problems.

    Moreover, the CDiplomat class will be used in various apps, which means I don't want to build my whole app around it, but instead make it someting "transportable".

    Then, I'd like that, every time MyDiplomat receives the "OnReceive" message, it transmits the newData to its owner (the MainWindow), and then calls a message called "UpdateRemoteData()" for exemple for display purpose. Or I could also forget the data transmission and only call from MyDiplomat the MainWindow::UpdateRemoteData() which will access to MyDiplomat data on its own while the MyDiplomat will be waiting till it is finished before accepting new incoming data.

    Code:
    class MainWindow : public CWnd
    {
         ...
         CDiplomat * MyDiplomat;
         ...
         CStaticText * IncomingDataDisplay;
         ...
         void UpdateRemoteData();
         ...
    }
    
    ...
    
    Byte * data;
    Long SizeOfData;
    
    ...
    
    class CDiplomat : public CAsyncSocket
    {
    
        OnReceive()
        {
            ...
            receive(data, &SizeOfData);
            ...
        }
    }
    
    }

    A few ideas I tried to explore did not meet success or did not convince me.
    Here they are :

    - Using a timer thread and checking through a global "flag" if new data is available (and unlocked), and then retrieve them. Then, the flag would have to be a mutex to avoid concurrency.
    - Trying to pass the "UpdateRemoteData" function as a pointer and store it into MyDiplomat... but I can't do that because can't pass a static pointer since I want to access the members of the MainWindow to update then with incoming data, and can't pass an instance function like in C.
    - Trying to implement a "Delegation-like" functionnality, like the Objective-C one. It sounded a bit weird to me... didn't go very far in this way: just an idea for now.
    - Trying to pass the MyDiplomat owner (the MainWindow instance) as an argument so that I can call the "UpdateRemoteData" through the pointer. But since I didn't know (and don't want it) the type of the owner, I cannot call a function on a (void *) pointer : or maybe it is possible but I didn't do it the correct way.

    Then, I for now don't know how to do it... suggestions are then welcome!

    Hope it was clear engouh to deserve your interest in it. Thanks for reading till the end, and thanks in advance for your suggestion about it.

  2. #2
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: How can an Asynchronous Socket transmit Data to its owner ?

    create an observer:
    Code:
    class DiplomatObserverIfc
    {
       public:
          virtual void dataAvailable() = 0;
    };
    and let your CDiplomat class take this interface in its constructor
    Code:
    class CDiplomat
    {
       public:
          explicit CDiplomat( DiplomatObserverIfc *ifc );
          // or
          explicit CDiplomat( DiplomatObserverIfc& ifc );
    };
    and store this interface in your CDiplomat class.
    Your MainWindow class must now pass this interface to the CDiplomat class when it creates it. You might want MainWindow to inheri from DiplomatObserverIfc.

    Each time your CDiplomat wants to tell its owner something, it can call dataAvailable().

    This "observer pattern" is widely used, I assume.

  3. #3
    Join Date
    Feb 2009
    Location
    Bretagne, France
    Posts
    5

    Re: How can an Asynchronous Socket transmit Data to its owner ?

    Thank you for your anwser.

    I feel really interested in your solution cause it was something I also tried to do... but : what was wrong was that if my MainWindow had to be inherited from both CWnd and DiplomatObserverIfc, and thus cannot be transmitted (though "this") to its MyDiplomat member because I assumed It was not possible to do this cast (MainWindow -> ).

    Then, through your suggestion it sounds like it is possible (assumed that I have understood).... I will try it again then.

    I also don't see how it is possible without double inheritance, though you suggested it is possible (or at least your suggestion sounded like).

  4. #4
    Join Date
    Feb 2009
    Location
    Bretagne, France
    Posts
    5

    Re: How can an Asynchronous Socket transmit Data to its owner ?

    Works.
    What I missed was the cast from (MainWindow) to (Oberver) when I passed "this" to the CDiplomat constructor.
    Didn't know much about multi inheritance, and know a little more now.
    THanks!

  5. #5
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: How can an Asynchronous Socket transmit Data to its owner ?

    there is no need for a cast if your MainWindow also inherits from the observer class. Simply pass "this" to the CDiplomat's constructor.

  6. #6
    Join Date
    Feb 2009
    Location
    Bretagne, France
    Posts
    5

    Re: How can an Asynchronous Socket transmit Data to its owner ?

    It failed (ie I received a runtime error) when I omited the cast.
    Then I supposed there was something related...
    Last edited by g_Marvin; February 16th, 2009 at 04:11 AM.

  7. #7
    Join Date
    May 2001
    Location
    Germany
    Posts
    1,158

    Re: How can an Asynchronous Socket transmit Data to its owner ?

    This should not require a cast:
    Code:
    class DiplomatObserverIfc
    {
       public:
          virtual void dataAvailable() = 0;
    };
    
    class MainWindow : public CWnd, private /*or public, as you like*/ DiplomatObserverIfc
    {
         ...
         CDiplomat * MyDiplomat;
         ...
         CStaticText * IncomingDataDisplay;
         ...
         void UpdateRemoteData();
        
         void dataAvailable();
         ...
    }
    
    class CDiplomat
    {
       public:
          explicit CDiplomat( DiplomatObserverIfc *ifc )
             : m_observer(ifc)
          {...}
    
       private:
    DiplomatObserverIfc *m_observer;
    ...
    }
    then at some point in the MainWindow class you do a
    Code:
    MyDiplomat = new CDiplomat(this);
    and whenever the MyDiplomat object wants to tell the MainWindow about new data
    Code:
    m_observer->dataAvailable();

  8. #8
    Join Date
    Feb 2009
    Location
    Bretagne, France
    Posts
    5

    Re: How can an Asynchronous Socket transmit Data to its owner ?

    Actually you were perfectly right : tried it again (without a cast), and it is ok now. Surely it used to be something else that made me think I needed a cast (or maybe I am just stubborn!).

    Thanks a lot for your help.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured