<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1"> <title>connection.cpp Source File</title> <link href="doxygen.css" rel="stylesheet" type="text/css"> </head><body> <!-- Generated by Doxygen 1.2.17 --> <center> <a class="qindex" href="main.html">Main Page</a> <a class="qindex" href="namespaces.html">Namespace List</a> <a class="qindex" href="classes.html">Alphabetical List</a> <a class="qindex" href="annotated.html">Compound List</a> <a class="qindex" href="files.html">File List</a> <a class="qindex" href="functions.html">Compound Members</a> <a class="qindex" href="globals.html">File Members</a> <a class="qindex" href="pages.html">Related Pages</a> </center> <hr><h1>connection.cpp</h1><a href="connection_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 00008 <span class="preprocessor">#include "<a class="code" href="sysconfig_8h.html">sysconfig.h</a>"</span> 00009 <span class="preprocessor">#include "<a class="code" href="connection_8h.html">connection.h</a>"</span> 00010 <span class="preprocessor">#include "<a class="code" href="socket_8h.html">socket.h</a>"</span> 00011 <span class="preprocessor">#include "<a class="code" href="server_8h.html">server.h</a>"</span> 00012 <span class="preprocessor">#include "<a class="code" href="log_8h.html">log.h</a>"</span> 00013 <a name="l00018"></a><a class="code" href="classConnection.html#a0">00018</a> <a class="code" href="classConnection.html#a0">Connection::Connection</a>(SOCKET sock, <a class="code" href="classServer.html">Server</a>* server) 00019 : mServer(server), mDisconnectable(false) { 00020 <a class="code" href="classConnection.html#n1">mSock</a> = <span class="keyword">new</span> <a class="code" href="classSocket.html">Socket</a>(sock); 00021 } 00022 <a name="l00026"></a><a class="code" href="classConnection.html#a1">00026</a> <a class="code" href="classConnection.html#a1">Connection::~Connection</a>() { 00027 <span class="keyword">delete</span> <a class="code" href="classConnection.html#n1">mSock</a>; 00028 } 00029 <a name="l00033"></a><a class="code" href="classConnection.html#a2">00033</a> <a class="code" href="classConnection.html#a0">Connection::Connection</a>(<span class="keyword">const</span> <a class="code" href="classConnection.html">Connection</a>& r_conn) 00034 : mServer(r_conn.mServer), mDisconnectable(r_conn.mDisconnectable), 00035 mInBuffer(r_conn.mInBuffer), mOutBuffer(r_conn.mOutBuffer), 00036 mPendingInput(r_conn.mPendingInput) { 00037 <a class="code" href="classConnection.html#n1">mSock</a> = <span class="keyword">new</span> <a class="code" href="classSocket.html">Socket</a>(*r_conn.mSock); 00038 } 00039 <a name="l00043"></a><a class="code" href="classConnection.html#b0">00043</a> <a class="code" href="classConnection.html">Connection</a> & <a class="code" href="classConnection.html#b0">Connection::operator=</a>(<span class="keyword">const</span> <a class="code" href="classConnection.html">Connection</a>& r_conn) { 00044 <span class="keywordflow">if</span> (<span class="keyword">this</span> == &r_conn) 00045 <span class="keywordflow">return</span> *<span class="keyword">this</span>; 00046 <a class="code" href="classConnection.html#n0">mServer</a> = r_conn.<a class="code" href="classConnection.html#n0">mServer</a>; 00047 <a class="code" href="classConnection.html#n3">mInBuffer</a> = r_conn.<a class="code" href="classConnection.html#n3">mInBuffer</a>; 00048 <a class="code" href="classConnection.html#n4">mOutBuffer</a> = r_conn.<a class="code" href="classConnection.html#n4">mOutBuffer</a>; 00049 <a class="code" href="classConnection.html#n5">mPendingInput</a> = r_conn.<a class="code" href="classConnection.html#n5">mPendingInput</a>; 00050 <span class="keyword">delete</span> <a class="code" href="classConnection.html#n1">mSock</a>; 00051 <a class="code" href="classConnection.html#n1">mSock</a> = <span class="keyword">new</span> <a class="code" href="classSocket.html">Socket</a>(*r_conn.<a class="code" href="classConnection.html#n1">mSock</a>); 00052 <span class="keywordflow">return</span> *<span class="keyword">this</span>; 00053 } 00054 <a name="l00059"></a><a class="code" href="classConnection.html#a3">00059</a> <span class="keywordtype">bool</span> <a class="code" href="classConnection.html#a3">Connection::operator==</a>(<span class="keyword">const</span> <a class="code" href="classConnection.html">Connection</a>& r_conn)<span class="keyword"> const </span>{ 00060 <span class="keywordflow">return</span> (<a class="code" href="classConnection.html#a11">GetSocket</a>() == r_conn.<a class="code" href="classConnection.html#a11">GetSocket</a>()); 00061 } 00062 <a name="l00073"></a><a class="code" href="classConnection.html#a4">00073</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a4">Connection::HandleInput</a>() { 00074 <span class="comment">// Loop to gather all socket input.</span> 00075 <span class="keywordflow">while</span>(true) { 00076 <span class="keywordtype">char</span> c; 00077 <span class="keywordflow">try</span> { 00078 c = <a class="code" href="classConnection.html#n1">mSock</a>-><a class="code" href="classSocket.html#a3">Read</a>(); 00079 } 00080 <span class="keywordflow">catch</span> (<a class="code" href="classBlockingException.html">BlockingException</a> &ex) { 00081 <span class="comment">// Indicates no more input can be squeezed from this socket.</span> 00082 <span class="comment">// Let's bust this loop</span> 00083 <a class="code" href="classConnection.html#n0">mServer</a>-><a class="code" href="classServer.html#a4">ServerLog</a>().<a class="code" href="classLog.html#a3">Write</a>(<span class="stringliteral">"INFO-Connection(recv): Blocking %d on %d"</span>, 00084 ex.mErrCode, <a class="code" href="classConnection.html#a11">GetSocket</a>()); 00085 <span class="keywordflow">break</span>; 00086 } 00087 <span class="keywordflow">catch</span> (<a class="code" href="classShutdownException.html">ShutdownException</a> &ex) { 00088 <a class="code" href="classConnection.html#n2">mDisconnectable</a> = <span class="keyword">true</span>; 00089 <span class="comment">// Connection is scheduled for disconnection, and we'll exit</span> 00090 <a class="code" href="classConnection.html#n0">mServer</a>-><a class="code" href="classServer.html#a4">ServerLog</a>().<a class="code" href="classLog.html#a3">Write</a>(<span class="stringliteral">"WARNING-Connection(recv): Shutdown %d on %d"</span>, 00091 ex.mErrCode, <a class="code" href="classConnection.html#a11">GetSocket</a>()); 00092 <span class="keywordflow">return</span>; 00093 } 00094 <span class="keywordflow">catch</span> (<a class="code" href="classIOErrorException.html">IOErrorException</a> &ex) { 00095 <span class="comment">// We have a serious error</span> 00096 <span class="comment">// Connection is scheduled for disconnection, and we'll exit</span> 00097 <a class="code" href="classConnection.html#n0">mServer</a>-><a class="code" href="classServer.html#a4">ServerLog</a>().<a class="code" href="classLog.html#a3">Write</a>(<span class="stringliteral">"ERROR-Connection(recv): IOError %d on %d"</span>, 00098 ex.mErrCode, <a class="code" href="classConnection.html#a11">GetSocket</a>()); 00099 <a class="code" href="classConnection.html#n2">mDisconnectable</a> = <span class="keyword">true</span>; 00100 <span class="keywordflow">return</span>; 00101 } 00102 <span class="comment">// Append everything read to our string.</span> 00103 <a class="code" href="classConnection.html#n5">mPendingInput</a> += c; 00104 <span class="comment">// Let's yield every 4K of input</span> 00105 <span class="keywordflow">if</span> (<a class="code" href="classConnection.html#n5">mPendingInput</a>.size() > 4096) 00106 <span class="keywordflow">break</span>; 00107 } <span class="comment">// while</span> 00108 00109 <span class="comment">// Loop to parse all the input into lines for our buffer</span> 00110 <span class="keywordflow">while</span>(true) { 00111 <span class="keywordtype">int</span> pos = <a class="code" href="classConnection.html#n5">mPendingInput</a>.find(<span class="stringliteral">"\r\n"</span>); 00112 <span class="keywordflow">if</span> (pos != (int)<a class="code" href="classConnection.html#n5">mPendingInput</a>.npos) { 00113 <span class="comment">// A line was found; save it to buffer and remove from input string</span> 00114 <a class="code" href="classConnection.html#n3">mInBuffer</a>.push_back(<a class="code" href="classConnection.html#n5">mPendingInput</a>.substr(0,pos)); 00115 <a class="code" href="classConnection.html#n5">mPendingInput</a>.erase(0,pos + 2); 00116 } <span class="keywordflow">else</span> { 00117 <span class="comment">// No more complete lines found</span> 00118 <span class="keywordflow">break</span>; 00119 } 00120 } 00121 } 00122 <a name="l00135"></a><a class="code" href="classConnection.html#a5">00135</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a5">Connection::HandleOutput</a>() { 00136 <span class="comment">// If there is any output waiting in line buffer write it out</span> 00137 <span class="keywordflow">while</span> (!<a class="code" href="classConnection.html#n4">mOutBuffer</a>.empty()) { 00138 <span class="keywordflow">try</span> { 00139 <a class="code" href="classConnection.html#n1">mSock</a>-><a class="code" href="classSocket.html#a4">Write</a>(<a class="code" href="classConnection.html#n4">mOutBuffer</a>.front()); 00140 <a class="code" href="classConnection.html#n4">mOutBuffer</a>.pop_front(); 00141 <a class="code" href="classConnection.html#n1">mSock</a>-><a class="code" href="classSocket.html#a8">Flush</a>(); 00142 } 00143 <span class="keywordflow">catch</span> (<a class="code" href="classBlockingException.html">BlockingException</a> &ex) { 00144 <span class="comment">// :bug: we don't save where we last were in the output.</span> 00145 <a class="code" href="classConnection.html#n0">mServer</a>-><a class="code" href="classServer.html#a4">ServerLog</a>().<a class="code" href="classLog.html#a3">Write</a>(<span class="stringliteral">"INFO-Connection(send): Blocking %d on %d"</span>, 00146 ex.mErrCode, <a class="code" href="classConnection.html#a11">GetSocket</a>()); 00147 <span class="keywordflow">return</span>; 00148 } 00149 <span class="keywordflow">catch</span> (<a class="code" href="classIOErrorException.html">IOErrorException</a> &ex) { 00150 <span class="comment">// severe error set socket as disconnectable and leave</span> 00151 <a class="code" href="classConnection.html#n0">mServer</a>-><a class="code" href="classServer.html#a4">ServerLog</a>().<a class="code" href="classLog.html#a3">Write</a>(<span class="stringliteral">"ERROR-Connection(send): IOError %d on %d"</span>, 00152 ex.mErrCode, <a class="code" href="classConnection.html#a11">GetSocket</a>()); 00153 <a class="code" href="classConnection.html#n2">mDisconnectable</a> = <span class="keyword">true</span>; 00154 <span class="keywordflow">return</span>; 00155 } 00156 } <span class="comment">// while</span> 00157 } 00158 <a name="l00162"></a><a class="code" href="classConnection.html#a8">00162</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a8">Connection::Disconnect</a>() { 00163 <a class="code" href="classConnection.html#n0">mServer</a>-><a class="code" href="classServer.html#a4">ServerLog</a>().<a class="code" href="classLog.html#a3">Write</a>( 00164 <span class="stringliteral">"INFO-Connection(disconnect): Connection %d disconnected"</span>, <a class="code" href="classConnection.html#a11">GetSocket</a>()); 00165 <a class="code" href="classConnection.html#n1">mSock</a>-><a class="code" href="classSocket.html#a10">Close</a>(); 00166 } 00167 <a name="l00173"></a><a class="code" href="classConnection.html#a9">00173</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a9">Connection::SendMsg</a>(<span class="keyword">const</span> string& r_msg) { 00174 <a class="code" href="classConnection.html#n4">mOutBuffer</a>.push_back(r_msg); 00175 } 00176 <a name="l00185"></a><a class="code" href="classConnection.html#a10">00185</a> string* <a class="code" href="classConnection.html#a10">Connection::ReadMsg</a>() { 00186 <span class="keywordflow">if</span> (!<a class="code" href="classConnection.html#n3">mInBuffer</a>.empty()) { 00187 string * msg = <span class="keyword">new</span> string(<a class="code" href="classConnection.html#n3">mInBuffer</a>.front()); 00188 <a class="code" href="classConnection.html#n3">mInBuffer</a>.pop_front(); 00189 <span class="keywordflow">return</span> msg; 00190 } 00191 <span class="keywordflow">return</span> NULL; 00192 } 00193 <a name="l00202"></a><a class="code" href="classConnection.html#a6">00202</a> <span class="keywordtype">bool</span> <a class="code" href="classConnection.html#a6">Connection::CanBeDisconnected</a>() { 00203 <span class="keywordflow">return</span> <a class="code" href="classConnection.html#n2">mDisconnectable</a>; 00204 } 00205 <a name="l00211"></a><a class="code" href="classConnection.html#a11">00211</a> SOCKET <a class="code" href="classConnection.html#a11">Connection::GetSocket</a>()<span class="keyword"> const </span>{ 00212 <span class="keywordflow">return</span> <a class="code" href="classConnection.html#n1">mSock</a>-><a class="code" href="classSocket.html#a9">GetSocket</a>(); 00213 } 00214 <a name="l00221"></a><a class="code" href="classConnection.html#a7">00221</a> <span class="keywordtype">bool</span> <a class="code" href="classConnection.html#a7">Connection::HasOutput</a>() { 00222 <span class="keywordflow">return</span> !<a class="code" href="classConnection.html#n4">mOutBuffer</a>.empty(); 00223 } 00224 </pre></div><hr><address style="align: right;"><small>Generated on Mon Mar 29 23:12:52 2004 for Paradigm by <a href="http://www.doxygen.org/index.html"> <img src="doxygen.png" alt="doxygen" align="middle" border=0 width=110 height=53></a>1.2.17 </small></address> </body> </html>