Click here to Skip to main content
15,881,559 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.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>RCF: TcpAsioServerTransport.hpp Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
<link href="tabs.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.4.5 -->
<div class="tabs">
  <ul>
    <li><a href="main.html"><span>Main&nbsp;Page</span></a></li>
    <li><a href="annotated.html"><span>Data&nbsp;Structures</span></a></li>
    <li id="current"><a href="files.html"><span>Files</span></a></li>
    <li><a href="dirs.html"><span>Directories</span></a></li>
  </ul></div>
<div class="nav">
<a class="el" href="dir_G_3A_2FDevelopment_2Fbuild_2Fscripts_2Fwin_2FBuildRcf2_5FOutput_2FRCF_2D0_2E4_2Finclude_2F.html">include</a>&nbsp;&raquo&nbsp;<a class="el" href="dir_G_3A_2FDevelopment_2Fbuild_2Fscripts_2Fwin_2FBuildRcf2_5FOutput_2FRCF_2D0_2E4_2Finclude_2FRCF_2F.html">RCF</a></div>
<h1>TcpAsioServerTransport.hpp</h1><div class="fragment"><pre class="fragment"><a name="l00001"></a>00001 
<a name="l00002"></a>00002 <span class="comment">//*****************************************************************************</span>
<a name="l00003"></a>00003 <span class="comment">// RCF - Remote Call Framework</span>
<a name="l00004"></a>00004 <span class="comment">// Copyright (c) 2005. All rights reserved.</span>
<a name="l00005"></a>00005 <span class="comment">// Developed by Jarl Lindrud.</span>
<a name="l00006"></a>00006 <span class="comment">// Contact: jlindrud@hotmail.com .</span>
<a name="l00007"></a>00007 <span class="comment">//*****************************************************************************</span>
<a name="l00008"></a>00008 
<a name="l00009"></a>00009 <span class="preprocessor">#ifndef INCLUDE_RCF_TCPASIOSERVERTRANSPORT_HPP</span>
<a name="l00010"></a>00010 <span class="preprocessor"></span><span class="preprocessor">#define INCLUDE_RCF_TCPASIOSERVERTRANSPORT_HPP</span>
<a name="l00011"></a>00011 <span class="preprocessor"></span>
<a name="l00012"></a>00012 <span class="preprocessor">#include &lt;set&gt;</span>
<a name="l00013"></a>00013 <span class="preprocessor">#include &lt;vector&gt;</span>
<a name="l00014"></a>00014 
<a name="l00015"></a>00015 <span class="preprocessor">#include &lt;boost/enable_shared_from_this.hpp&gt;</span>
<a name="l00016"></a>00016 <span class="preprocessor">#include &lt;boost/shared_ptr.hpp&gt;</span>
<a name="l00017"></a>00017 <span class="preprocessor">#include &lt;boost/weak_ptr.hpp&gt;</span>
<a name="l00018"></a>00018 
<a name="l00019"></a>00019 <span class="preprocessor">#include &lt;boost/asio.hpp&gt;</span>
<a name="l00020"></a>00020 
<a name="l00021"></a>00021 <span class="preprocessor">#include &lt;RCF/IpAddress.hpp&gt;</span>
<a name="l00022"></a>00022 <span class="preprocessor">#include &lt;RCF/IpServerTransport.hpp&gt;</span>
<a name="l00023"></a>00023 <span class="preprocessor">#include &lt;RCF/ServerTransport.hpp&gt;</span>
<a name="l00024"></a>00024 <span class="preprocessor">#include &lt;RCF/Service.hpp&gt;</span>
<a name="l00025"></a>00025 <span class="preprocessor">#include &lt;RCF/ThreadLibrary.hpp&gt;</span>
<a name="l00026"></a>00026 
<a name="l00027"></a>00027 <span class="keyword">namespace </span>RCF {
<a name="l00028"></a>00028 
<a name="l00029"></a>00029     <span class="keyword">namespace </span>asio = boost::asio;
<a name="l00030"></a>00030 
<a name="l00031"></a>00031     <span class="keyword">class </span>RcfServer;
<a name="l00032"></a>00032     <span class="keyword">class </span>TcpAsioSynchronizedSocket;
<a name="l00033"></a>00033 
<a name="l00034"></a>00034     <span class="keyword">typedef</span> asio::io_service                    Demuxer;
<a name="l00035"></a>00035     <span class="keyword">typedef</span> boost::shared_ptr&lt;Demuxer&gt;          DemuxerPtr;
<a name="l00036"></a>00036     <span class="keyword">typedef</span> asio::ip::tcp::acceptor             SocketAcceptor;
<a name="l00037"></a>00037     <span class="keyword">typedef</span> boost::shared_ptr&lt;SocketAcceptor&gt;   SocketAcceptorPtr;
<a name="l00038"></a>00038     <span class="keyword">typedef</span> asio::deadline_timer                DeadlineTimer;
<a name="l00039"></a>00039     <span class="keyword">typedef</span> boost::shared_ptr&lt;DeadlineTimer&gt;    DeadlineTimerPtr;
<a name="l00040"></a>00040 
<a name="l00041"></a>00041     <span class="keyword">class </span>TcpAsioServerTransport : 
<a name="l00042"></a>00042         <span class="keyword">public</span> I_ServerTransport, 
<a name="l00043"></a>00043         <span class="keyword">public</span> I_ServerTransportEx, 
<a name="l00044"></a>00044         <span class="keyword">public</span> I_IpServerTransport,
<a name="l00045"></a>00045         <span class="keyword">public</span> I_Service
<a name="l00046"></a>00046     {
<a name="l00047"></a>00047     <span class="keyword">public</span>:
<a name="l00048"></a>00048 
<a name="l00049"></a>00049         TcpAsioServerTransport(<span class="keywordtype">int</span> port);
<a name="l00050"></a>00050         ServerTransportPtr clone();
<a name="l00051"></a>00051 
<a name="l00052"></a>00052     <span class="keyword">private</span>:
<a name="l00053"></a>00053 
<a name="l00054"></a>00054         <span class="keyword">typedef</span> boost::shared_ptr&lt;I_Session&gt; SessionPtr;
<a name="l00055"></a>00055         <span class="keyword">typedef</span> boost::weak_ptr&lt;I_Session&gt; SessionWeakPtr;
<a name="l00056"></a>00056         <span class="keyword">typedef</span> TcpAsioSynchronizedSocket SynchronizedSocket;
<a name="l00057"></a>00057         <span class="keyword">typedef</span> boost::shared_ptr&lt;SynchronizedSocket&gt; SynchronizedSocketPtr;
<a name="l00058"></a>00058         
<a name="l00059"></a>00059         <span class="keyword">class </span>TcpAsioProactor;
<a name="l00060"></a>00060 
<a name="l00061"></a>00061         <span class="keyword">class </span>SessionState : <span class="keyword">public</span> boost::enable_shared_from_this&lt;SessionState&gt;, boost::noncopyable
<a name="l00062"></a>00062         {
<a name="l00063"></a>00063         <span class="keyword">public</span>:
<a name="l00064"></a>00064             
<a name="l00065"></a>00065             SessionState(TcpAsioServerTransport &amp;transport, DemuxerPtr demuxerPtr, ReadWriteMutexPtr readWriteMutexPtr);
<a name="l00066"></a>00066             ~SessionState();
<a name="l00067"></a>00067 
<a name="l00068"></a>00068             <span class="keywordtype">void</span>            setSessionPtr(SessionPtr sessionPtr) { mSessionPtr = sessionPtr; }
<a name="l00069"></a>00069             SessionPtr      getSessionPtr() { <span class="keywordflow">return</span> mSessionPtr; }
<a name="l00070"></a>00070 
<a name="l00071"></a>00071             <span class="keywordtype">void</span>            close();
<a name="l00072"></a>00072             <span class="keywordtype">void</span>            invokeAsyncAccept();
<a name="l00073"></a>00073 
<a name="l00074"></a>00074         <span class="keyword">private</span>:
<a name="l00075"></a>00075 
<a name="l00076"></a>00076             <span class="keywordtype">void</span>            filteredRead(<span class="keywordtype">char</span> *buffer, std::size_t bufferLen);
<a name="l00077"></a>00077             <span class="keywordtype">void</span>            filteredWrite(<span class="keyword">const</span> <span class="keywordtype">char</span> *buffer, std::size_t bufferLen);
<a name="l00078"></a>00078             <span class="keywordtype">void</span>            filteredReadWriteCompletion(<span class="keyword">const</span> asio::error &amp;error, size_t bytesTransferred);
<a name="l00079"></a>00079             <span class="keywordtype">void</span>            unfilteredReadWriteCompletion(std::size_t bytesTransferred, <span class="keywordtype">int</span> error);
<a name="l00080"></a>00080             <span class="keywordtype">void</span>            setTransportFilters(<span class="keyword">const</span> std::vector&lt;FilterPtr&gt; &amp;filters);
<a name="l00081"></a>00081             <span class="keywordtype">void</span>            invokeAsyncRead();
<a name="l00082"></a>00082             <span class="keywordtype">void</span>            invokeAsyncWrite();
<a name="l00083"></a>00083             <span class="keywordtype">void</span>            onAccept(<span class="keyword">const</span> asio::error&amp; error);
<a name="l00084"></a>00084             <span class="keywordtype">void</span>            onReadWrite(<span class="keyword">const</span> asio::error&amp; error, size_t bytesTransferred);
<a name="l00085"></a>00085             <span class="keywordtype">void</span>            onReflectedReadWrite(<span class="keyword">const</span> asio::error&amp; error, size_t bytesTransferred);
<a name="l00086"></a>00086 
<a name="l00087"></a>00087 
<a name="l00088"></a>00088             <span class="comment">// TODO: too many friends</span>
<a name="l00089"></a>00089             <span class="keyword">friend</span> <span class="keyword">class    </span>TcpAsioServerTransport;
<a name="l00090"></a>00090             <span class="keyword">friend</span> <span class="keyword">class    </span>TcpAsioProactor;
<a name="l00091"></a>00091             
<a name="l00092"></a>00092             <span class="keyword">enum</span> State 
<a name="l00093"></a>00093             {
<a name="l00094"></a>00094                 Ready,
<a name="l00095"></a>00095                 Accepting,
<a name="l00096"></a>00096                 ReadingDataCount,
<a name="l00097"></a>00097                 ReadingData,
<a name="l00098"></a>00098                 WritingData
<a name="l00099"></a>00099             };
<a name="l00100"></a>00100 
<a name="l00101"></a>00101             State                               mState;
<a name="l00102"></a>00102             std::vector&lt;char&gt;                   mReadBuffer;
<a name="l00103"></a>00103             std::size_t                         mReadBufferRemaining;
<a name="l00104"></a>00104             std::vector&lt;char&gt;                   mWriteBuffer;
<a name="l00105"></a>00105             std::size_t                         mWriteBufferRemaining;
<a name="l00106"></a>00106             <span class="comment">//boost::weak_ptr&lt;I_Session&gt;          mSessionWeakPtr;</span>
<a name="l00107"></a>00107             boost::shared_ptr&lt;I_Session&gt;        mSessionPtr;
<a name="l00108"></a>00108             std::vector&lt;FilterPtr&gt;              mTransportFilters;
<a name="l00109"></a>00109             SynchronizedSocketPtr               mSynchronizedSocketPtr;
<a name="l00110"></a>00110             SynchronizedSocketPtr               mReflectorSocketPtr;
<a name="l00111"></a>00111             <span class="keyword">volatile</span> <span class="keywordtype">bool</span>                       mReflecting;
<a name="l00112"></a>00112             IpAddress                           mIpAddress;
<a name="l00113"></a>00113             TcpAsioServerTransport &amp;            mTransport;
<a name="l00114"></a>00114         };
<a name="l00115"></a>00115 
<a name="l00116"></a>00116         <span class="keyword">typedef</span> boost::shared_ptr&lt;SessionState&gt; SessionStatePtr;
<a name="l00117"></a>00117         <span class="keyword">typedef</span> boost::weak_ptr&lt;SessionState&gt; SessionStateWeakPtr;
<a name="l00118"></a>00118 
<a name="l00119"></a>00119         <span class="keyword">class </span>TcpAsioProactor : <span class="keyword">public</span> I_Proactor
<a name="l00120"></a>00120         {
<a name="l00121"></a>00121         <span class="keyword">private</span>:
<a name="l00122"></a>00122             <span class="comment">// TODO: too many frioends</span>
<a name="l00123"></a>00123             <span class="keyword">friend</span> <span class="keyword">class </span>SessionState;
<a name="l00124"></a>00124             <span class="keyword">friend</span> <span class="keyword">class </span>TcpAsioServerTransport;
<a name="l00125"></a>00125 
<a name="l00126"></a>00126             TcpAsioProactor(TcpAsioServerTransport &amp;tcpAsioServerTransport);
<a name="l00127"></a>00127 
<a name="l00128"></a>00128             <span class="keywordtype">void</span>                        postRead();
<a name="l00129"></a>00129             <span class="keywordtype">void</span>                        postWrite();
<a name="l00130"></a>00130             <span class="keywordtype">void</span>                        postClose();
<a name="l00131"></a>00131             std::vector&lt;char&gt; &amp;         getWriteBuffer();
<a name="l00132"></a>00132             std::size_t                 getWriteOffset();
<a name="l00133"></a>00133             std::vector&lt;char&gt; &amp;         getReadBuffer();
<a name="l00134"></a>00134             std::size_t                 getReadOffset();
<a name="l00135"></a>00135             I_ServerTransport &amp;         getServerTransport();
<a name="l00136"></a>00136             <span class="keyword">const</span> I_RemoteAddress &amp;     getRemoteAddress();
<a name="l00137"></a>00137             <span class="keywordtype">void</span>                        setTransportFilters(<span class="keyword">const</span> std::vector&lt;FilterPtr&gt; &amp;filters);
<a name="l00138"></a>00138         
<a name="l00139"></a>00139             SessionStateWeakPtr         mSessionStateWeakPtr;
<a name="l00140"></a>00140             <span class="comment">//SessionStatePtr             mSessionStatePtr;</span>
<a name="l00141"></a>00141             TcpAsioServerTransport &amp;    mTcpAsioServerTransport;
<a name="l00142"></a>00142         };
<a name="l00143"></a>00143 
<a name="l00144"></a>00144         <span class="keyword">typedef</span> boost::shared_ptr&lt;TcpAsioProactor&gt; TcpAsioProactorPtr;
<a name="l00145"></a>00145 
<a name="l00146"></a>00146         SessionStatePtr createSessionState();
<a name="l00147"></a>00147         
<a name="l00148"></a>00148         <span class="comment">// I_ServerTransportEx implementation</span>
<a name="l00149"></a>00149         ClientTransportAutoPtr          createClientTransport(<span class="keyword">const</span> I_Endpoint &amp;endpoint);
<a name="l00150"></a>00150         boost::shared_ptr&lt;I_Session&gt;    createServerSession(ClientTransportAutoPtr clientTransportAutoPtr);
<a name="l00151"></a>00151         ClientTransportAutoPtr          createClientTransport(boost::shared_ptr&lt;I_Session&gt; sessionPtr);
<a name="l00152"></a>00152         <span class="keywordtype">bool</span>                            reflect(boost::shared_ptr&lt;I_Session&gt; sessionPtr1, boost::shared_ptr&lt;I_Session&gt; sessionPtr2);
<a name="l00153"></a>00153         <span class="keywordtype">bool</span>                            isConnected(boost::shared_ptr&lt;I_Session&gt; sessionPtr);
<a name="l00154"></a>00154         
<a name="l00155"></a>00155         <span class="comment">// I_Service implementation</span>
<a name="l00156"></a>00156         <span class="keywordtype">void</span>                open();
<a name="l00157"></a>00157         <span class="keywordtype">void</span>                close();
<a name="l00158"></a>00158         <span class="keywordtype">bool</span>                cycle(<span class="keywordtype">int</span> timeoutMs, <span class="keyword">const</span> <span class="keyword">volatile</span> <span class="keywordtype">bool</span> &amp;stopFlag);
<a name="l00159"></a>00159         <span class="keywordtype">void</span>                stop();
<a name="l00160"></a>00160         <span class="keywordtype">void</span>                stopCycle(<span class="keyword">const</span> asio::error &amp;error);
<a name="l00161"></a>00161         <span class="keywordtype">void</span>                onServiceAdded(RcfServer &amp;server);
<a name="l00162"></a>00162         <span class="keywordtype">void</span>                onServiceRemoved(RcfServer &amp;server);
<a name="l00163"></a>00163         <span class="keywordtype">void</span>                onServerOpen(RcfServer &amp;server);
<a name="l00164"></a>00164         <span class="keywordtype">void</span>                onServerClose(RcfServer &amp;server);
<a name="l00165"></a>00165         <span class="keywordtype">void</span>                onServerStart(RcfServer &amp;server);
<a name="l00166"></a>00166         <span class="keywordtype">void</span>                onServerStop(RcfServer &amp;server);
<a name="l00167"></a>00167         <span class="keywordtype">void</span>                setServer(RcfServer &amp;server);
<a name="l00168"></a>00168 
<a name="l00169"></a>00169         RcfServer &amp;         getServer();
<a name="l00170"></a>00170         I_SessionManager &amp;  getSessionManager();
<a name="l00171"></a>00171 
<a name="l00172"></a>00172     <span class="keyword">private</span>:
<a name="l00173"></a>00173 
<a name="l00174"></a>00174         <span class="keyword">friend</span> <span class="keyword">class        </span>SessionState;
<a name="l00175"></a>00175 
<a name="l00176"></a>00176         DemuxerPtr          mDemuxerPtr;
<a name="l00177"></a>00177         ReadWriteMutexPtr   mReadWriteMutexPtr;
<a name="l00178"></a>00178         <span class="keywordtype">int</span>                 mPort;
<a name="l00179"></a>00179         SocketAcceptorPtr   mAcceptorPtr;
<a name="l00180"></a>00180         DeadlineTimerPtr    mCycleTimerPtr;
<a name="l00181"></a>00181         <span class="keywordtype">bool</span>                mInterrupt;
<a name="l00182"></a>00182         <span class="keyword">volatile</span> <span class="keywordtype">bool</span>       mStopFlag;
<a name="l00183"></a>00183         RcfServer *         pServer;
<a name="l00184"></a>00184 
<a name="l00185"></a>00185         std::set&lt;SessionStatePtr&gt;   mSessionStates;
<a name="l00186"></a>00186 
<a name="l00187"></a>00187     };
<a name="l00188"></a>00188 
<a name="l00189"></a>00189 } <span class="comment">// namespace RCF</span>
<a name="l00190"></a>00190 
<a name="l00191"></a>00191 <span class="preprocessor">#endif // ! INCLUDE_RCF_TCPASIOSERVERTRANSPORT_HPP</span>
</pre></div><hr size="1"><address style="align: right;"><small>Generated on Tue Sep 19 19:02:37 2006 for RCF by&nbsp;
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border="0"></a> 1.4.5 </small></address>
</body>
</html>

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