ACE Tutorial 015
Building a protocol stream

Recv is the sibling to Xmit. Again, they could be combined into a single object if you want.

An ACE_Stream is designed to handle downstream traffic very well. You put() data into it and it flows along towards the tail. However, there doesn't seem to be a way to put data in such that it will travel upstream. To get around that, I've added a get() method to Recv that will trigger a read on the socket. Recv will then put the data to the next upstream module and we're on our way. As noted earlier, that data will eventually show up either in the reader (if installed on the stream open()) or the stream head reader task's message queue.

    // page16.html,v 1.16 2003/08/19 15:08:26 schmidt Exp

    #ifndef RECV_H
    #define RECV_h

    #include "Protocol_Task.h"

    class ACE_SOCK_Stream;

    /* Get some data from the peer and send it upstream for
       de-protocol-ization.
    */
    class Recv : public Protocol_Task
    {
    public:
      typedef Protocol_Task inherited;

      // Give it someone to talk to...
      Recv (ACE_SOCK_Stream &peer);
      ~Recv (void);

      // Trigger a read from the socket
      int get (void);

      // In some cases it might be easier to check the "state" of the Recv
      // object than to rely on return codes filtering back to you.
      int error (void)
      {
        return this->error_;
      }

    protected:

      ACE_SOCK_Stream &peer (void)
      {
        return this->peer_;
      }

      // The baseclass will trigger this when our get() method is called.
      // A message block of the appropriate size is created, filled and
      // passed up the stream.
      int recv (ACE_Message_Block *message,
                ACE_Time_Value *timeout = 0);

    private:
      // Our endpoint
      ACE_SOCK_Stream &peer_;

      // get() uses a bogus message block to cause the baseclass to invoke
      // recv().  To avoid memory thrashing, we create that bogus message
      // once and reuse it for the life of Recv.
      ACE_Message_Block *tickler_;

      // Our error flag (duh)
      int error_;
    };

    #endif /* RECV_H */

[Tutorial Index] [Continue This Tutorial]