00001
00009 #include "sysconfig.h"
00010 #include "server.h"
00011 #include "event.h"
00012
00016 Server::Server(EventQueue& r_inque, EventQueue& r_outque, Log& r_lgfile)
00017 : mShutdown(false), mrLog(r_lgfile),
00018 mrInQueue(r_inque), mrOutQueue(r_outque) {
00019 }
00020
00028 Server::~Server() {
00029 ConnList::iterator i;
00030 for (i = mConns.begin(); i != mConns.end(); i++) {
00031 delete (*i);
00032 }
00033 }
00034
00041 bool Server::Boot(unsigned short port) {
00042
00043 mAcceptor = socket (AF_INET, SOCK_STREAM, 0);
00044 if (mAcceptor == INVALID_SOCKET) {
00045 ServerLog().Write("ERROR-Server(socket): %d", WSAGetLastError());
00046 return false;
00047 }
00048
00049
00050 if (!SetNonBlocking(mAcceptor))
00051 return false;
00052
00053
00054 int sockopt_val = 1;
00055
00056 if (setsockopt(mAcceptor, SOL_SOCKET, SO_REUSEADDR, (char *)&sockopt_val,
00057 sizeof(sockopt_val)) == SOCKET_ERROR) {
00058 ServerLog().Write("ERROR-Server(setsockopt): %d",WSAGetLastError());
00059 closesocket(mAcceptor);
00060 return false;
00061 }
00062
00063
00064 mTo.sin_family = AF_INET;
00065 mTo.sin_addr.s_addr = INADDR_ANY;
00066 mTo.sin_port = htons(port);
00067 if (bind(mAcceptor, (struct sockaddr *)&mTo, sizeof(mTo)) == SOCKET_ERROR) {
00068 ServerLog().Write("ERROR-Server(bind): %d",WSAGetLastError());
00069 closesocket(mAcceptor);
00070 return false;
00071 }
00072
00073 if (listen(mAcceptor, 5) == SOCKET_ERROR) {
00074 ServerLog().Write("ERROR-Server(listen): %d",WSAGetLastError());
00075 closesocket(mAcceptor);
00076 return false;
00077 }
00078
00079
00080
00081
00082
00083
00084
00085
00086 mNumFds = mAcceptor;
00087 return true;
00088 }
00089
00102 #pragma argsused
00103 void Server::Run(void * parms) {
00104 ServerLog().Write("INFO-StartServer(): Server thread entered.");
00105 struct timeval timeout = { 0, 1 };
00106
00107 while (!mShutdown) {
00108 ConnList::iterator i, curr;
00109
00110
00111 InitFDs();
00112
00113
00114 if (select(mNumFds + 1, &mInputFDs, &mOutputFDs, NULL, &timeout) == SOCKET_ERROR) {
00115 ServerLog().Write("ERROR-Server(select): %d",WSAGetLastError());
00116 break;
00117 }
00118
00119
00120 if (FD_ISSET(mAcceptor, &mInputFDs)) {
00121 AcceptConnection();
00122 }
00123
00124
00125 for(i = mConns.begin(); i != mConns.end(); i++) {
00126 if (FD_ISSET((*i)->GetSocket(), &mInputFDs)) {
00127 (*i)->HandleInput();
00128
00129
00130 string* msg = (*i)->ReadMsg();
00131 while(msg) {
00132
00133 mrOutQueue.Push(new Event(MESSAGE_E,
00134 (*i)->GetSocket(), msg->length(), msg->c_str()));
00135 delete msg;
00136 msg = (*i)->ReadMsg();
00137 }
00138 }
00139 }
00140
00141
00142 ProcessQueue();
00143
00144
00145 for(i = mConns.begin(); i != mConns.end(); i++) {
00146 if (FD_ISSET((*i)->GetSocket(), &mOutputFDs))
00147 (*i)->HandleOutput();
00148 }
00149
00150
00151 for(i = mConns.begin(); i != mConns.end();) {
00152 curr = i++;
00153 if ((*curr)->CanBeDisconnected()) {
00154 (*curr)->Disconnect();
00155
00156 mrOutQueue.Push(new Event(DISCONNECT_E, (*curr)->GetSocket(),
00157 0, NULL));
00158 delete (*curr);
00159 mConns.erase(curr);
00160 }
00161 }
00162 }
00163 ShutdownServer();
00164 ServerLog().Write("INFO-StartServer(): Server thread exited.");
00165 }
00166
00174 void Server::AcceptConnection() {
00175 struct sockaddr_in addr;
00176 int addrlen = sizeof(addr);
00177
00178
00179 SOCKET psock = accept(mAcceptor, (struct sockaddr *)&addr, &addrlen);
00180 if (psock != INVALID_SOCKET) {
00181
00182 if (SetNonBlocking(psock)) {
00183
00184 Connection *conn = new Connection(psock, this);
00185 ServerLog().Write("INFO-Server(accept): Connection %d accepted", psock);
00186 mConns.push_back(conn);
00187
00188 mrOutQueue.Push(new Event(CONNECT_E, conn->GetSocket(), 0, NULL));
00189 }
00190 } else {
00191
00192 ServerLog().Write("ERROR-ServerAccept(accept): %d", WSAGetLastError());
00193 }
00194 }
00195
00211 void Server::InitFDs () {
00212 FD_ZERO (&mInputFDs);
00213 FD_ZERO (&mOutputFDs);
00214
00215 FD_SET (mAcceptor, &mInputFDs);
00216 for(ConnList::iterator i = mConns.begin(); i != mConns.end(); i++) {
00217
00218
00219
00220
00221
00222
00223 mNumFds = max(mNumFds, (*i)->GetSocket());
00224 FD_SET((*i)->GetSocket(), &mInputFDs);
00225 if ((*i)->HasOutput())
00226 FD_SET((*i)->GetSocket(), &mOutputFDs);
00227 }
00228 }
00229
00244 void Server::ProcessQueue() {
00245
00246 Event* e;
00247 while ((e = mrInQueue.Pop()) != NULL) {
00248 switch (e->mEventType) {
00249 case DISCONNECT_E:
00250
00251 {
00252
00253 }
00254 break;
00255 case CONNECT_E:
00256
00257 break;
00258 case MESSAGE_E:
00259
00260 {
00261
00262 if (e->mpData && e->mDataLen) {
00263 string msg;
00264 msg.append(e->mpData, e->mDataLen);
00265 for(ConnList::iterator c = mConns.begin(); c != mConns.end(); c++) {
00266 if ((*c)->GetSocket() == e->mClientId) {
00267 (*c)->SendMsg(msg);
00268
00269 FD_SET ((*c)->GetSocket(), &mOutputFDs);
00270 }
00271 }
00272 }
00273 }
00274 break;
00275 case SHUTDOWN_E:
00276
00277 mShutdown = true;
00278 break;
00279 case NONE_E:
00280 break;
00281 }
00282 delete e;
00283 }
00284 }
00285
00291 void Server::ShutdownServer() {
00292 ServerLog().Write("INFO-Server(shutdown): Server shutting down");
00293 ConnList::iterator ci, curr;
00294 for(ci = mConns.begin(); ci != mConns.end();) {
00295 curr = ci++;
00296
00297 (*curr)->Disconnect();
00298
00299 mrOutQueue.Push(new Event(DISCONNECT_E, (*curr)->GetSocket(),
00300 0, NULL));
00301 delete (*curr);
00302 mConns.erase(curr);
00303 }
00304 closesocket(mAcceptor);
00305 mrOutQueue.Push(new Event(SHUTDOWN_E, 0, 0, 0));
00306 }
00307
00314 Log& Server::ServerLog() {
00315 return mrLog;
00316 }
00317
00325 bool Server::SetNonBlocking(SOCKET s) {
00326 unsigned long ioctl_cmd = 1;
00327 if (ioctlsocket(s, FIONBIO, &ioctl_cmd) == SOCKET_ERROR) {
00328 ServerLog().Write("ERROR-Server(SetNonBlocking): %d on socket %d",
00329 WSAGetLastError(), s);
00330 closesocket(s);
00331 return false;
00332 }
00333 return true;
00334 }
00335