Click here to Skip to main content
15,895,546 members
Articles / Programming Languages / C++

RCF - Interprocess Communication for C++

Rate me:
Please Sign up or sign in to vote.
4.94/5 (147 votes)
25 Oct 2011CPOL20 min read 4.6M   8.4K   331  
A server/client IPC framework, using the C++ preprocessor as an IDL compiler.
//*****************************************************************************
// RCF - Remote Call Framework
// Copyright (c) 2005. All rights reserved.
// Developed by Jarl Lindrud.
// Contact: jlindrud@hotmail.com .
//*****************************************************************************

#ifndef INCLUDE_RCF_TCPASIOCLIENT_TRANSPORT_HPP
#define INCLUDE_RCF_TCPASIOCLIENT_TRANSPORT_HPP

#include <boost/shared_ptr.hpp>
#include <boost/asio.hpp>

#include <RCF/ClientTransport.hpp>
#include <RCF/ThreadLibrary.hpp>

namespace RCF {

    namespace asio = boost::asio;

    class                               TcpAsioSynchronizedSocket;
    class                               TcpAsioServerTransport;
    typedef asio::io_service            Demuxer;
    typedef boost::shared_ptr<Demuxer>  DemuxerPtr;

    class TcpAsioClientTransport : public I_ClientTransport
    {
    public:
        TcpAsioClientTransport(const std::string &ip, int port, DemuxerPtr demuxerPtr = getSharedDemuxerPtr()/* DemuxerPtr()*/);
        TcpAsioClientTransport(const TcpAsioClientTransport &rhs);
        ~TcpAsioClientTransport();

        // I_ClientTransport implementation
        ClientTransportAutoPtr      clone() const;
        EndpointPtr                 getEndpointPtr() const;
        int                         send(const std::string &data, unsigned int timeoutMs);
        int                         receive(std::string &data, unsigned int timeoutMs);
        bool                        isConnected();
        void                        close();
        void                        setTransportFilters(const std::vector<FilterPtr> &filters);

    private:
        friend class TcpAsioServerTransport;
        typedef TcpAsioSynchronizedSocket               SynchronizedSocket;
        typedef boost::shared_ptr<SynchronizedSocket>   SynchronizedSocketPtr;
        TcpAsioClientTransport(SynchronizedSocketPtr synchronizedSocketPtr, DemuxerPtr demuxerPtr = getSharedDemuxerPtr()/* DemuxerPtr()*/);
        SynchronizedSocketPtr       releaseSynchronizedSocketPtr();
        SynchronizedSocketPtr       getSynchronizedSocketPtr();

    private:
        int                         connect();
        void                        readSingle(char *buffer, std::size_t bufferLen);
        void                        writeSingle(const char *buffer, std::size_t bufferLen);
        std::size_t                 read(char *buffer, std::size_t bufferLen);
        std::size_t                 write(const char *buffer, std::size_t bufferLen);
        int                         errFromAsioErr();
        void                        onFilteredReadWriteCompletion(std::size_t bytesTransferred, int error);

        // shared instance functions
    private:
        class State;
        typedef boost::shared_ptr<State>    StatePtr;
        
        static ReadWriteMutexPtr *  spReadWriteMutexPtr;
        static DemuxerPtr *         spDemuxerPtr;
    public:
        static void                 init();
        static void                 deinit();
        static ReadWriteMutexPtr    getSharedReadWriteMutexPtr();
        static DemuxerPtr           getSharedDemuxerPtr();

        // data
    private:

        class State
        {
        public:
            State(Demuxer &demuxer) : mTimer(demuxer), mBytesTransferred(), mTimeoutFlag() {}
            asio::deadline_timer mTimer;
            std::size_t mBytesTransferred;
            volatile bool mTimeoutFlag;
            asio::error mError;
            Mutex mEventMutex;
            Condition mEvent;
        };
        
        DemuxerPtr                          mDemuxerPtr;
        SynchronizedSocketPtr               mSynchronizedSocketPtr;
        
        // following are at times generated lazily, hence the mutable
        mutable std::string                 mIp;
        mutable int                         mPort;
        mutable asio::ip::tcp::endpoint     mEndpoint;

        std::vector<FilterPtr>              mTransportFilters;
        std::vector<char>                   mReadBuffer;
        std::vector<char>                   mWriteBuffer;
        unsigned int                        mEndTimeMs;
        
        StatePtr                            mStatePtr;

        asio::deadline_timer &              mTimer;
        std::size_t &                       mBytesTransferred;
        volatile bool &                     mTimeoutFlag;
        asio::error &                       mError;
        Mutex &                             mEventMutex;
        Condition &                         mEvent;
    };

} // namespace RCF

#endif // ! INCLUDE_RCF_TCPASIOCLIENT_TRANSPORT_HPP

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Australia Australia
Software developer, from Sweden and now living in Canberra, Australia, working on distributed C++ applications. When he is not programming, Jarl enjoys skiing and playing table tennis. He derives immense satisfaction from referring to himself in third person.

Comments and Discussions