<!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>