<!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 00009 <span class="preprocessor">#include "<a class="code" href="sysconfig_8h.html">sysconfig.h</a>"</span> 00010 <span class="preprocessor">#include "<a class="code" href="connection_8h.html">connection.h</a>"</span> 00011 00012 00017 <span class="comment">//##ModelId=3ED44BF10253</span> <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) 00019 : mSock(sock), mpPendingInput(NULL), mpPendingOutput(NULL), 00020 mDisconnectable(false) {} 00021 00025 <span class="comment">//##ModelId=3ED44BF10255</span> <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#n4">mpPendingOutput</a>; 00028 <span class="keyword">delete</span>[] <a class="code" href="classConnection.html#n5">mpPendingInput</a>; 00029 } 00030 00034 <span class="comment">//##ModelId=3ED44BF1025E</span> <a name="l00035"></a><a class="code" href="classConnection.html#a2">00035</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) 00036 : mDisconnectable(r_conn.mDisconnectable), mSock(r_conn.mSock), 00037 mpPendingInput(NULL), mpPendingOutput(NULL) { 00038 <a class="code" href="classConnection.html#n2">mInBuffer</a> = r_conn.mInBuffer; 00039 <a class="code" href="classConnection.html#n3">mOutBuffer</a> = r_conn.mOutBuffer; 00040 <span class="keywordflow">if</span> (r_conn.mpPendingInput) { 00041 <a class="code" href="classConnection.html#n5">mpPendingInput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(r_conn.mpPendingInput) + 1]; 00042 strcpy(<a class="code" href="classConnection.html#n5">mpPendingInput</a>, r_conn.mpPendingInput); 00043 } 00044 <span class="keywordflow">if</span> (r_conn.mpPendingOutput) { 00045 <a class="code" href="classConnection.html#n4">mpPendingOutput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(r_conn.mpPendingOutput) + 1]; 00046 strcpy(<a class="code" href="classConnection.html#n4">mpPendingOutput</a>, r_conn.mpPendingOutput); 00047 } 00048 } 00049 00053 <span class="comment">//##ModelId=3ED44BF10288</span> <a name="l00054"></a><a class="code" href="classConnection.html#b0">00054</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) { 00055 <span class="keywordflow">if</span> (<span class="keyword">this</span> == &r_conn) 00056 <span class="keywordflow">return</span> * <span class="keyword">this</span>; 00057 <a class="code" href="classConnection.html#n2">mInBuffer</a> = r_conn.<a class="code" href="classConnection.html#n2">mInBuffer</a>; 00058 <a class="code" href="classConnection.html#n3">mOutBuffer</a> = r_conn.<a class="code" href="classConnection.html#n3">mOutBuffer</a>; 00059 <span class="keywordflow">if</span> (r_conn.<a class="code" href="classConnection.html#n5">mpPendingInput</a>) { 00060 <a class="code" href="classConnection.html#n5">mpPendingInput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(r_conn.<a class="code" href="classConnection.html#n5">mpPendingInput</a>) + 1]; 00061 strcpy(<a class="code" href="classConnection.html#n5">mpPendingInput</a>, r_conn.<a class="code" href="classConnection.html#n5">mpPendingInput</a>); 00062 } 00063 <span class="keywordflow">if</span> (r_conn.<a class="code" href="classConnection.html#n4">mpPendingOutput</a>) { 00064 <a class="code" href="classConnection.html#n4">mpPendingOutput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(r_conn.<a class="code" href="classConnection.html#n4">mpPendingOutput</a>) + 1]; 00065 strcpy(<a class="code" href="classConnection.html#n4">mpPendingOutput</a>, r_conn.<a class="code" href="classConnection.html#n4">mpPendingOutput</a>); 00066 } 00067 <span class="keywordflow">return</span> *<span class="keyword">this</span>; 00068 } 00069 00086 <span class="comment">//##ModelId=3ED44BF10260</span> <a name="l00087"></a><a class="code" href="classConnection.html#a3">00087</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a3">Connection::HandleInput</a>() { 00088 string strin; 00089 <span class="keywordtype">char</span> inbuf[4096]; 00090 <span class="comment">// If there was input leftover from the last call to HandleInput</span> 00091 <span class="comment">// prepend it to the input string and clear it.</span> 00092 <span class="keywordflow">if</span> (mpPendingInput) { 00093 strin.append(<a class="code" href="classConnection.html#n5">mpPendingInput</a>); 00094 <span class="keyword">delete</span>[] <a class="code" href="classConnection.html#n5">mpPendingInput</a>; 00095 <a class="code" href="classConnection.html#n5">mpPendingInput</a> = NULL; 00096 } 00097 <span class="comment">// Loop to gather all socket input in 4K chunks.</span> 00098 <span class="keywordflow">while</span> (true) { 00099 <span class="keywordtype">int</span> nbytes = recv (<a class="code" href="classConnection.html#n0">mSock</a>, inbuf, 4096, 0); 00100 <span class="keywordflow">if</span> (nbytes == 0) { 00101 <span class="comment">// Connection is scheduled for disconnection, and we'll exit</span> 00102 <a class="code" href="classConnection.html#n1">mDisconnectable</a> = <span class="keyword">true</span>; 00103 <span class="keywordflow">return</span> ; 00104 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (nbytes == SOCKET_ERROR) { 00105 <span class="keywordtype">int</span> err = WSAGetLastError (); 00106 <span class="keywordflow">if</span> (err == WSAEWOULDBLOCK) { 00107 <span class="comment">// Indicates no more input can be squeezed from this socket.</span> 00108 <span class="comment">// Let's bust this loop</span> 00109 <span class="keywordflow">break</span>; 00110 } <span class="keywordflow">else</span> { 00111 <span class="comment">// We have a serious error</span> 00112 <span class="comment">// Connection is scheduled for disconnection, and we'll exit</span> 00113 cout << <span class="stringliteral">"Error-Connection(recv):"</span> << err << <span class="stringliteral">" on "</span> << <a class="code" href="classConnection.html#n0">mSock</a> << endl; 00114 <a class="code" href="classConnection.html#n1">mDisconnectable</a> = <span class="keyword">true</span>; 00115 <span class="keywordflow">return</span> ; 00116 } 00117 } 00118 <span class="comment">// Append everything read to our string.</span> 00119 inbuf[nbytes] = <span class="charliteral">'\0'</span>; 00120 strin.append(inbuf); 00121 } 00122 <span class="comment">// Loop to parse all input into lines for our buffer</span> 00123 <span class="keywordflow">while</span> (true) { 00124 <span class="keywordtype">int</span> pos = strin.find(<span class="stringliteral">"\r\n"</span>); 00125 <span class="keywordflow">if</span> (pos != (int)strin.npos) { 00126 <span class="comment">// A line was found; save it to buffer and remove from input string</span> 00127 <a class="code" href="classConnection.html#n2">mInBuffer</a>.push_back(strin.substr(0, pos)); 00128 strin.erase(0, pos + 2); 00129 } <span class="keywordflow">else</span> { 00130 <span class="comment">// No more complete lines found</span> 00131 <span class="keywordflow">if</span> (!strin.empty()) { 00132 <span class="comment">// Save leftovers into pending input array</span> 00133 <a class="code" href="classConnection.html#n5">mpPendingInput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strin.size() + 1]; 00134 strcpy(<a class="code" href="classConnection.html#n5">mpPendingInput</a>, strin.c_str()); 00135 } 00136 <span class="keywordflow">break</span>; 00137 } 00138 } 00139 } 00140 00153 <span class="comment">//##ModelId=3ED44BF10268</span> <a name="l00154"></a><a class="code" href="classConnection.html#a4">00154</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a4">Connection::HandleOutput</a>() { 00155 string strout; 00156 <span class="comment">// If there is output left to be sent from last time append</span> 00157 <span class="comment">// it to our output string</span> 00158 <span class="keywordflow">if</span> (mpPendingOutput) { 00159 strout.append(<a class="code" href="classConnection.html#n4">mpPendingOutput</a>); 00160 <span class="keyword">delete</span>[] <a class="code" href="classConnection.html#n4">mpPendingOutput</a>; 00161 <a class="code" href="classConnection.html#n4">mpPendingOutput</a> = NULL; 00162 } 00163 <span class="comment">// If there is any output waiting in line buffer append the first line</span> 00164 <span class="keywordflow">if</span> (!<a class="code" href="classConnection.html#n3">mOutBuffer</a>.empty()) { 00165 strout.append(<a class="code" href="classConnection.html#n3">mOutBuffer</a>.front()); 00166 <a class="code" href="classConnection.html#n3">mOutBuffer</a>.pop_front(); 00167 } 00168 <span class="comment">// Loop until our output string is empty</span> 00169 <span class="keywordflow">while</span> (!strout.empty()) { 00170 <span class="keyword">const</span> <span class="keywordtype">char</span> * pstr = strout.c_str(); 00171 <span class="keywordflow">while</span> (pstr) { <span class="comment">// Loop until we have written this string</span> 00172 <span class="keywordtype">int</span> nbytes = send (<a class="code" href="classConnection.html#n0">mSock</a>, pstr, strlen(pstr), 0); 00173 <span class="keywordflow">if</span> (nbytes == SOCKET_ERROR) { 00174 <span class="keywordtype">int</span> err = WSAGetLastError (); 00175 <span class="keywordflow">if</span> (err == WSAEWOULDBLOCK) { 00176 <span class="comment">// socket will block - save unwritten output in pending array</span> 00177 <span class="comment">// and leave</span> 00178 <a class="code" href="classConnection.html#n4">mpPendingOutput</a> = <span class="keyword">new</span> <span class="keywordtype">char</span>[strlen(pstr) + 1]; 00179 strcpy(<a class="code" href="classConnection.html#n4">mpPendingOutput</a>, pstr); 00180 <span class="keywordflow">return</span> ; 00181 } 00182 <span class="comment">// severe error set socket as disconnectable and leave</span> 00183 cout << <span class="stringliteral">"Error-Connection(recv):"</span> << err << <span class="stringliteral">" on "</span> << <a class="code" href="classConnection.html#n0">mSock</a> << endl; 00184 <a class="code" href="classConnection.html#n1">mDisconnectable</a> = <span class="keyword">true</span>; 00185 <span class="keywordflow">return</span> ; 00186 } <span class="keywordflow">else</span> <span class="keywordflow">if</span> (nbytes < (int)strlen(pstr)) { 00187 pstr += nbytes; 00188 } <span class="keywordflow">else</span> { 00189 pstr = NULL; 00190 } 00191 } 00192 strout.erase(); 00193 <span class="comment">// fetch next line in buffer if not empty</span> 00194 <span class="keywordflow">if</span> (!<a class="code" href="classConnection.html#n3">mOutBuffer</a>.empty()) { 00195 strout.append(<a class="code" href="classConnection.html#n3">mOutBuffer</a>.front()); 00196 <a class="code" href="classConnection.html#n3">mOutBuffer</a>.pop_front(); 00197 } 00198 } 00199 } 00200 00204 <span class="comment">//##ModelId=3ED44BF10272</span> <a name="l00205"></a><a class="code" href="classConnection.html#a6">00205</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a6">Connection::Disconnect</a>() { 00206 <span class="keywordtype">char</span> inbuf[4096]; 00207 <span class="keywordtype">bool</span> done = <span class="keyword">false</span>; 00208 shutdown(<a class="code" href="classConnection.html#n0">mSock</a>, SD_SEND); 00209 <span class="keywordflow">while</span> (!done) { 00210 <span class="keywordtype">int</span> nbytes = recv (<a class="code" href="classConnection.html#n0">mSock</a>, inbuf, 4096, 0); 00211 <span class="keywordflow">if</span> (!nbytes || nbytes == SOCKET_ERROR) 00212 done = <span class="keyword">true</span>; 00213 } 00214 closesocket(<a class="code" href="classConnection.html#n0">mSock</a>); 00215 } 00216 00222 <span class="comment">//##ModelId=3ED44BF10274</span> <a name="l00223"></a><a class="code" href="classConnection.html#a7">00223</a> <span class="keywordtype">void</span> <a class="code" href="classConnection.html#a7">Connection::SendMsg</a>(<span class="keyword">const</span> string& r_msg) { 00224 <a class="code" href="classConnection.html#n3">mOutBuffer</a>.push_back(r_msg); 00225 } 00226 00232 <span class="comment">//##ModelId=3ED44BF1027D</span> <a name="l00233"></a><a class="code" href="classConnection.html#a8">00233</a> string* <a class="code" href="classConnection.html#a8">Connection::ReadMsg</a>() { 00234 <span class="keywordflow">if</span> (!<a class="code" href="classConnection.html#n2">mInBuffer</a>.empty()) { 00235 string msg = <a class="code" href="classConnection.html#n2">mInBuffer</a>.front(); 00236 <a class="code" href="classConnection.html#n2">mInBuffer</a>.pop_front(); 00237 <span class="keywordflow">return</span> <span class="keyword">new</span> string(msg); 00238 } 00239 <span class="keywordflow">return</span> NULL; 00240 } 00241 00250 <span class="comment">//##ModelId=3ED44BF1026A</span> <a name="l00251"></a><a class="code" href="classConnection.html#a5">00251</a> <span class="keywordtype">bool</span> <a class="code" href="classConnection.html#a5">Connection::CanBeDisconnected</a>() { 00252 <span class="keywordflow">return</span> <a class="code" href="classConnection.html#n1">mDisconnectable</a>; 00253 } 00254 00260 <span class="comment">//##ModelId=3ED44BF10286</span> <a name="l00261"></a><a class="code" href="classConnection.html#a9">00261</a> SOCKET <a class="code" href="classConnection.html#a9">Connection::GetSocket</a>() { 00262 <span class="keywordflow">return</span> <a class="code" href="classConnection.html#n0">mSock</a>; 00263 } </pre></div><hr><address style="align: right;"><small>Generated on Mon Mar 29 22:38:41 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>