00001
00010 #include "sysconfig.h"
00011 #include "server.h"
00012
00013
00014 Server* Server::sInstance = 0;
00015
00016
00020
00021
00022 Server::Server() : mShutdown(false) {}
00023
00027
00028 Server::~Server() {
00029 ConnList::iterator i;
00030 for (i = mUsers.begin(); i != mUsers.end();) {
00031 delete (*i);
00032 }
00033 }
00034
00040
00041 Server* Server::Instance() {
00042 if (sInstance == 0)
00043 sInstance = new Server;
00044 return sInstance;
00045 }
00046
00050
00051 void Server::Destroy() {
00052 delete sInstance;
00053 }
00054
00061
00062 bool Server::Boot(unsigned short port) {
00063 unsigned long flags = 1;
00064 int opt = 1;
00065 mTo.sin_family = AF_INET;
00066 mTo.sin_addr.s_addr = INADDR_ANY;
00067 mTo.sin_port = htons (port);
00068
00069
00070 mAcceptor = socket (AF_INET, SOCK_STREAM, 0);
00071 if (mAcceptor == INVALID_SOCKET) {
00072 cout << "ERROR-Server(socket):" << WSAGetLastError () << endl;
00073 return false;
00074 }
00075
00076 if (ioctlsocket (mAcceptor, FIONBIO, &flags) == SOCKET_ERROR) {
00077 cout << "ERROR-Server(ioctlsocket):" << WSAGetLastError () << endl;
00078 return false;
00079 }
00080 if (setsockopt (mAcceptor, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof (opt)) == SOCKET_ERROR) {
00081 cout << "ERROR-Server(setsockopt):" << WSAGetLastError () << endl;
00082 closesocket (mAcceptor);
00083 return false;
00084 }
00085 if (bind (mAcceptor, (struct sockaddr *) &mTo, sizeof (mTo)) == SOCKET_ERROR) {
00086 cout << "ERROR-Server(bind):" << WSAGetLastError () << endl;
00087 closesocket (mAcceptor);
00088 return false;
00089 }
00090 if (listen (mAcceptor, 5) == SOCKET_ERROR) {
00091 cout << "ERROR-Server(listen):" << WSAGetLastError () << endl;
00092 return false;
00093 }
00094 return true;
00095 }
00096
00103
00104 void Server::Run() {
00105 struct timeval timeout;
00106 timeout.tv_sec = 60;
00107 timeout.tv_usec = 0;
00108 ConnList::iterator i, curr;
00109
00110 while (!mShutdown) {
00111 InitFDs();
00112 if (select(0, &mInputFDs, &mOutputFDs, NULL, &timeout) == SOCKET_ERROR) {
00113 cout << "ERROR-Server(select):" << WSAGetLastError () << endl;
00114 break;
00115 }
00116 Execute();
00117 if (FD_ISSET(mAcceptor, &mInputFDs)) {
00118 Connection * c = AcceptConnection();
00119 if (c) {
00120 c->SendMsg("Welcome!\r\n");
00121 mUsers.push_back(c);
00122 }
00123 }
00124 for (i = mUsers.begin(); i != mUsers.end(); i++) {
00125 if (FD_ISSET((*i)->GetSocket(), &mOutputFDs))
00126 (*i)->HandleOutput();
00127 if (FD_ISSET((*i)->GetSocket(), &mInputFDs))
00128 (*i)->HandleInput();
00129 }
00130 for (i = mUsers.begin(); i != mUsers.end();) {
00131 curr = i++;
00132 if ((*curr)->CanBeDisconnected()) {
00133 (*curr)->Disconnect();
00134 delete (*curr);
00135 mUsers.erase(curr);
00136 }
00137 }
00138 }
00139 ShutdownServer();
00140 }
00141
00148
00149 Connection* Server::AcceptConnection() {
00150 struct sockaddr_in from;
00151 Connection *conn;
00152 int fromlen = sizeof (from);
00153 SOCKET psock = accept (mAcceptor, (struct sockaddr *) & from, &fromlen);
00154 if (psock == INVALID_SOCKET) {
00155 return NULL;
00156 } else {
00157 unsigned long flags = 1;
00158 ioctlsocket (psock, FIONBIO, &flags);
00159 conn = new Connection(psock);
00160 return conn;
00161 }
00162 }
00163
00174
00175 void Server::InitFDs () {
00176 FD_ZERO (&mInputFDs);
00177 FD_ZERO (&mOutputFDs);
00178 FD_SET (mAcceptor, &mInputFDs);
00179 for (ConnList::iterator i = mUsers.begin(); i != mUsers.end(); i++) {
00180 FD_SET ((*i)->GetSocket(), &mInputFDs);
00181 FD_SET ((*i)->GetSocket(), &mOutputFDs);
00182 }
00183 }
00184
00194
00195 void Server::Execute() {
00196 ConnList::iterator i, o;
00197 string* msg;
00198 for (i = mUsers.begin(); i != mUsers.end(); i++) {
00199 while ((msg = (*i)->ReadMsg()) != NULL) {
00200 if (!msg->compare("@shutdown")) {
00201 mShutdown = true;
00202 for (o = mUsers.begin(); o != mUsers.end(); o++) {
00203 (*o)->SendMsg("Shutting down..BYE.\r\n");
00204 }
00205 delete msg;
00206 return ;
00207 }
00208 msg->append("\r\n");
00209 for (o = mUsers.begin(); o != mUsers.end(); o++) {
00210 (*o)->SendMsg(*msg);
00211 }
00212 delete msg;
00213 }
00214 }
00215 }
00216
00223
00224 void Server::ShutdownServer() {
00225 ConnList::iterator i, curr;
00226 for (i = mUsers.begin(); i != mUsers.end();) {
00227 curr = i++;
00228 (*curr)->Disconnect();
00229 delete (*curr);
00230 mUsers.erase(curr);
00231 }
00232 closesocket(mAcceptor);
00233 }
00234