<!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>server.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>server.cpp</h1><a href="server_8cpp.html">Go to the documentation of this file.</a><div class="fragment"><pre>00001 00010 <span class="preprocessor">#include "<a class="code" href="sysconfig_8h.html">sysconfig.h</a>"</span> 00011 <span class="preprocessor">#include "<a class="code" href="server_8h.html">server.h</a>"</span> 00012 00013 <span class="comment">//##ModelId=3ED44BF102A6</span> <a name="l00014"></a><a class="code" href="classServer.html#r0">00014</a> <a class="code" href="classServer.html">Server</a>* <a class="code" href="classServer.html#r0">Server::sInstance</a> = 0; 00015 00016 00020 <span class="comment">//##ModelId=3ED44BF10327</span> 00021 <span class="comment">//##ModelId=3ED44BF10330</span> <a name="l00022"></a><a class="code" href="classServer.html#c0">00022</a> <a class="code" href="classServer.html#c0">Server::Server</a>() : mShutdown(false) {} 00023 00027 <span class="comment">//##ModelId=3ED44BF1032F</span> <a name="l00028"></a><a class="code" href="classServer.html#c1">00028</a> <a class="code" href="classServer.html#c1">Server::~Server</a>() { 00029 ConnList::iterator i; 00030 <span class="keywordflow">for</span> (i = <a class="code" href="classServer.html#o5">mUsers</a>.begin(); i != <a class="code" href="classServer.html#o5">mUsers</a>.end();) { 00031 <span class="keyword">delete</span> (*i); 00032 } 00033 } 00034 00040 <span class="comment">//##ModelId=3ED44BF10311</span> <a name="l00041"></a><a class="code" href="classServer.html#d0">00041</a> <a class="code" href="classServer.html">Server</a>* <a class="code" href="classServer.html#d0">Server::Instance</a>() { 00042 <span class="keywordflow">if</span> (<a class="code" href="classServer.html#r0">sInstance</a> == 0) 00043 <a class="code" href="classServer.html#r0">sInstance</a> = <span class="keyword">new</span> <a class="code" href="classServer.html">Server</a>; 00044 <span class="keywordflow">return</span> <a class="code" href="classServer.html#r0">sInstance</a>; 00045 } 00046 00050 <span class="comment">//##ModelId=3ED44BF10325</span> <a name="l00051"></a><a class="code" href="classServer.html#d1">00051</a> <span class="keywordtype">void</span> <a class="code" href="classServer.html#d1">Server::Destroy</a>() { 00052 <span class="keyword">delete</span> <a class="code" href="classServer.html#r0">sInstance</a>; 00053 } 00054 00061 <span class="comment">//##ModelId=3ED44BF10313</span> <a name="l00062"></a><a class="code" href="classServer.html#a0">00062</a> <span class="keywordtype">bool</span> <a class="code" href="classServer.html#a0">Server::Boot</a>(<span class="keywordtype">unsigned</span> <span class="keywordtype">short</span> port) { 00063 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> flags = 1; 00064 <span class="keywordtype">int</span> opt = 1; 00065 <a class="code" href="classServer.html#o4">mTo</a>.sin_family = AF_INET; 00066 <a class="code" href="classServer.html#o4">mTo</a>.sin_addr.s_addr = INADDR_ANY; 00067 <a class="code" href="classServer.html#o4">mTo</a>.sin_port = htons (port); 00068 00069 <span class="comment">// Get a socket for the server to listen on.</span> 00070 <a class="code" href="classServer.html#o3">mAcceptor</a> = socket (AF_INET, SOCK_STREAM, 0); 00071 <span class="keywordflow">if</span> (<a class="code" href="classServer.html#o3">mAcceptor</a> == INVALID_SOCKET) { 00072 cout << <span class="stringliteral">"ERROR-Server(socket):"</span> << WSAGetLastError () << endl; 00073 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00074 } 00075 <span class="comment">// set it up to be non-blocking</span> 00076 <span class="keywordflow">if</span> (ioctlsocket (<a class="code" href="classServer.html#o3">mAcceptor</a>, FIONBIO, &flags) == SOCKET_ERROR) { 00077 cout << <span class="stringliteral">"ERROR-Server(ioctlsocket):"</span> << WSAGetLastError () << endl; 00078 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00079 } 00080 <span class="keywordflow">if</span> (setsockopt (<a class="code" href="classServer.html#o3">mAcceptor</a>, SOL_SOCKET, SO_REUSEADDR, (<span class="keywordtype">char</span> *) &opt, <span class="keyword">sizeof</span> (opt)) == SOCKET_ERROR) { 00081 cout << <span class="stringliteral">"ERROR-Server(setsockopt):"</span> << WSAGetLastError () << endl; 00082 closesocket (<a class="code" href="classServer.html#o3">mAcceptor</a>); 00083 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00084 } 00085 <span class="keywordflow">if</span> (bind (<a class="code" href="classServer.html#o3">mAcceptor</a>, (<span class="keyword">struct</span> sockaddr *) &<a class="code" href="classServer.html#o4">mTo</a>, <span class="keyword">sizeof</span> (<a class="code" href="classServer.html#o4">mTo</a>)) == SOCKET_ERROR) { 00086 cout << <span class="stringliteral">"ERROR-Server(bind):"</span> << WSAGetLastError () << endl; 00087 closesocket (<a class="code" href="classServer.html#o3">mAcceptor</a>); 00088 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00089 } 00090 <span class="keywordflow">if</span> (listen (<a class="code" href="classServer.html#o3">mAcceptor</a>, 5) == SOCKET_ERROR) { 00091 cout << <span class="stringliteral">"ERROR-Server(listen):"</span> << WSAGetLastError () << endl; 00092 <span class="keywordflow">return</span> <span class="keyword">false</span>; 00093 } 00094 <span class="keywordflow">return</span> <span class="keyword">true</span>; 00095 } 00096 00103 <span class="comment">//##ModelId=3ED44BF1031C</span> <a name="l00104"></a><a class="code" href="classServer.html#a1">00104</a> <span class="keywordtype">void</span> <a class="code" href="classServer.html#a1">Server::Run</a>() { 00105 <span class="keyword">struct </span>timeval timeout; 00106 timeout.tv_sec = 60; 00107 timeout.tv_usec = 0; 00108 ConnList::iterator i, curr; 00109 00110 <span class="keywordflow">while</span> (!<a class="code" href="classServer.html#o0">mShutdown</a>) { 00111 <a class="code" href="classServer.html#c5">InitFDs</a>(); 00112 <span class="keywordflow">if</span> (select(0, &<a class="code" href="classServer.html#o1">mInputFDs</a>, &<a class="code" href="classServer.html#o2">mOutputFDs</a>, NULL, &timeout) == SOCKET_ERROR) { 00113 cout << <span class="stringliteral">"ERROR-Server(select):"</span> << WSAGetLastError () << endl; 00114 <span class="keywordflow">break</span>; 00115 } 00116 <a class="code" href="classServer.html#c6">Execute</a>(); 00117 <span class="keywordflow">if</span> (FD_ISSET(<a class="code" href="classServer.html#o3">mAcceptor</a>, &<a class="code" href="classServer.html#o1">mInputFDs</a>)) { 00118 <a class="code" href="classConnection.html">Connection</a> * c = <a class="code" href="classServer.html#c4">AcceptConnection</a>(); 00119 <span class="keywordflow">if</span> (c) { 00120 c-><a class="code" href="classConnection.html#a7">SendMsg</a>(<span class="stringliteral">"Welcome!\r\n"</span>); 00121 <a class="code" href="classServer.html#o5">mUsers</a>.push_back(c); 00122 } 00123 } 00124 <span class="keywordflow">for</span> (i = <a class="code" href="classServer.html#o5">mUsers</a>.begin(); i != <a class="code" href="classServer.html#o5">mUsers</a>.end(); i++) { 00125 <span class="keywordflow">if</span> (FD_ISSET((*i)->GetSocket(), &<a class="code" href="classServer.html#o2">mOutputFDs</a>)) 00126 (*i)->HandleOutput(); 00127 <span class="keywordflow">if</span> (FD_ISSET((*i)->GetSocket(), &<a class="code" href="classServer.html#o1">mInputFDs</a>)) 00128 (*i)->HandleInput(); 00129 } 00130 <span class="keywordflow">for</span> (i = <a class="code" href="classServer.html#o5">mUsers</a>.begin(); i != <a class="code" href="classServer.html#o5">mUsers</a>.end();) { 00131 curr = i++; 00132 <span class="keywordflow">if</span> ((*curr)->CanBeDisconnected()) { 00133 (*curr)->Disconnect(); 00134 <span class="keyword">delete</span> (*curr); 00135 <a class="code" href="classServer.html#o5">mUsers</a>.erase(curr); 00136 } 00137 } 00138 } 00139 <a class="code" href="classServer.html#c7">ShutdownServer</a>(); 00140 } 00141 00148 <span class="comment">//##ModelId=3ED44BF10344</span> <a name="l00149"></a><a class="code" href="classServer.html#c4">00149</a> <a class="code" href="classConnection.html">Connection</a>* <a class="code" href="classServer.html#c4">Server::AcceptConnection</a>() { 00150 <span class="keyword">struct </span>sockaddr_in from; 00151 <a class="code" href="classConnection.html">Connection</a> *conn; 00152 <span class="keywordtype">int</span> fromlen = <span class="keyword">sizeof</span> (from); 00153 SOCKET psock = accept (<a class="code" href="classServer.html#o3">mAcceptor</a>, (<span class="keyword">struct</span> sockaddr *) & from, &fromlen); 00154 <span class="keywordflow">if</span> (psock == INVALID_SOCKET) { 00155 <span class="keywordflow">return</span> NULL; 00156 } <span class="keywordflow">else</span> { 00157 <span class="keywordtype">unsigned</span> <span class="keywordtype">long</span> flags = 1; 00158 ioctlsocket (psock, FIONBIO, &flags); 00159 conn = <span class="keyword">new</span> <a class="code" href="classConnection.html">Connection</a>(psock); 00160 <span class="keywordflow">return</span> conn; 00161 } 00162 } 00163 00174 <span class="comment">//##ModelId=3ED44BF1034D</span> <a name="l00175"></a><a class="code" href="classServer.html#c5">00175</a> <span class="keywordtype">void</span> <a class="code" href="classServer.html#c5">Server::InitFDs</a> () { 00176 FD_ZERO (&<a class="code" href="classServer.html#o1">mInputFDs</a>); 00177 FD_ZERO (&<a class="code" href="classServer.html#o2">mOutputFDs</a>); 00178 FD_SET (<a class="code" href="classServer.html#o3">mAcceptor</a>, &<a class="code" href="classServer.html#o1">mInputFDs</a>); 00179 <span class="keywordflow">for</span> (ConnList::iterator i = <a class="code" href="classServer.html#o5">mUsers</a>.begin(); i != <a class="code" href="classServer.html#o5">mUsers</a>.end(); i++) { 00180 FD_SET ((*i)->GetSocket(), &<a class="code" href="classServer.html#o1">mInputFDs</a>); 00181 FD_SET ((*i)->GetSocket(), &<a class="code" href="classServer.html#o2">mOutputFDs</a>); 00182 } 00183 } 00184 00194 <span class="comment">//##ModelId=3ED44BF1034E</span> <a name="l00195"></a><a class="code" href="classServer.html#c6">00195</a> <span class="keywordtype">void</span> <a class="code" href="classServer.html#c6">Server::Execute</a>() { 00196 ConnList::iterator i, o; 00197 string* msg; 00198 <span class="keywordflow">for</span> (i = <a class="code" href="classServer.html#o5">mUsers</a>.begin(); i != <a class="code" href="classServer.html#o5">mUsers</a>.end(); i++) { 00199 <span class="keywordflow">while</span> ((msg = (*i)->ReadMsg()) != NULL) { 00200 <span class="keywordflow">if</span> (!msg->compare(<span class="stringliteral">"@shutdown"</span>)) { 00201 <a class="code" href="classServer.html#o0">mShutdown</a> = <span class="keyword">true</span>; 00202 <span class="keywordflow">for</span> (o = <a class="code" href="classServer.html#o5">mUsers</a>.begin(); o != <a class="code" href="classServer.html#o5">mUsers</a>.end(); o++) { 00203 (*o)->SendMsg(<span class="stringliteral">"Shutting down..BYE.\r\n"</span>); 00204 } 00205 <span class="keyword">delete</span> msg; 00206 <span class="keywordflow">return</span> ; 00207 } 00208 msg->append(<span class="stringliteral">"\r\n"</span>); 00209 <span class="keywordflow">for</span> (o = <a class="code" href="classServer.html#o5">mUsers</a>.begin(); o != <a class="code" href="classServer.html#o5">mUsers</a>.end(); o++) { 00210 (*o)->SendMsg(*msg); 00211 } 00212 <span class="keyword">delete</span> msg; 00213 } 00214 } 00215 } 00216 00223 <span class="comment">//##ModelId=3ED44BF10357</span> <a name="l00224"></a><a class="code" href="classServer.html#c7">00224</a> <span class="keywordtype">void</span> <a class="code" href="classServer.html#c7">Server::ShutdownServer</a>() { 00225 ConnList::iterator i, curr; 00226 <span class="keywordflow">for</span> (i = <a class="code" href="classServer.html#o5">mUsers</a>.begin(); i != <a class="code" href="classServer.html#o5">mUsers</a>.end();) { 00227 curr = i++; 00228 (*curr)->Disconnect(); 00229 <span class="keyword">delete</span> (*curr); 00230 <a class="code" href="classServer.html#o5">mUsers</a>.erase(curr); 00231 } 00232 closesocket(<a class="code" href="classServer.html#o3">mAcceptor</a>); 00233 } 00234 </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>