<!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> &nbsp; <a class="qindex" href="namespaces.html">Namespace List</a> &nbsp; <a class="qindex" href="classes.html">Alphabetical List</a> &nbsp; <a class="qindex" href="annotated.html">Compound List</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Compound Members</a> &nbsp; <a class="qindex" href="globals.html">File Members</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </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 &lt;&lt; <span class="stringliteral">"ERROR-Server(socket):"</span> &lt;&lt; WSAGetLastError () &lt;&lt; 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, &amp;flags) == SOCKET_ERROR) {
00077         cout &lt;&lt; <span class="stringliteral">"ERROR-Server(ioctlsocket):"</span> &lt;&lt; WSAGetLastError () &lt;&lt; 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> *) &amp;opt, <span class="keyword">sizeof</span> (opt)) == SOCKET_ERROR) {
00081         cout &lt;&lt; <span class="stringliteral">"ERROR-Server(setsockopt):"</span> &lt;&lt; WSAGetLastError () &lt;&lt; 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 *) &amp;<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 &lt;&lt; <span class="stringliteral">"ERROR-Server(bind):"</span> &lt;&lt; WSAGetLastError () &lt;&lt; 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 &lt;&lt; <span class="stringliteral">"ERROR-Server(listen):"</span> &lt;&lt; WSAGetLastError () &lt;&lt; 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, &amp;<a class="code" href="classServer.html#o1">mInputFDs</a>, &amp;<a class="code" href="classServer.html#o2">mOutputFDs</a>, NULL, &amp;timeout) == SOCKET_ERROR) {
00113             cout &lt;&lt; <span class="stringliteral">"ERROR-Server(select):"</span> &lt;&lt; WSAGetLastError () &lt;&lt; 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>, &amp;<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-&gt;<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)-&gt;GetSocket(), &amp;<a class="code" href="classServer.html#o2">mOutputFDs</a>))
00126                 (*i)-&gt;HandleOutput();
00127             <span class="keywordflow">if</span> (FD_ISSET((*i)-&gt;GetSocket(), &amp;<a class="code" href="classServer.html#o1">mInputFDs</a>))
00128                 (*i)-&gt;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)-&gt;CanBeDisconnected()) {
00133                 (*curr)-&gt;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 *) &amp; from, &amp;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, &amp;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 (&amp;<a class="code" href="classServer.html#o1">mInputFDs</a>);
00177     FD_ZERO (&amp;<a class="code" href="classServer.html#o2">mOutputFDs</a>);
00178     FD_SET (<a class="code" href="classServer.html#o3">mAcceptor</a>, &amp;<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)-&gt;GetSocket(), &amp;<a class="code" href="classServer.html#o1">mInputFDs</a>);
00181         FD_SET ((*i)-&gt;GetSocket(), &amp;<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)-&gt;ReadMsg()) != NULL) {
00200             <span class="keywordflow">if</span> (!msg-&gt;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)-&gt;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-&gt;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)-&gt;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)-&gt;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>