Main Page | Class Hierarchy | Alphabetical List | Class List | File List | Class Members

server.h

00001 /*******************************************************************/
00002 /*  Class BasicTcpServer:-  Generic, one-thread-per-client server. */
00003 /*                                                                 */
00004 /*      Class BasicTcpServer takes care of socket connections      */
00005 /*      and threading. Derived classes must implement method       */
00006 /*      doServerOp. This is the operation that the specific        */
00007 /*      server performs repeatedly for each client.                */
00008 /*      This class can only be used as a base class ie it          */
00009 /*  cannot be instantiated on its own.                         */
00010 /*                                                                 */
00011 /*      <a href="mailto:Simon.Hoyle@csiro.au">Simon Hoyle</a>      */
00012 /*  Original: 15-2-2001                                        */
00013 /*      Revised:  25-8-2004                                        */
00014 /*******************************************************************/     
00015 
00016 
00017 #ifndef SERVER_H
00018 #define SERVER_H
00019 
00020 #include <iostream>
00021 #ifdef SOLARIS
00022 #include <stdio.h>
00023 #endif
00024 #include <pthread.h>
00025 #include <time.h>
00026 #include <netdb.h>
00027 #include <sys/types.h>
00028 #include <sys/socket.h>
00029 #include <arpa/inet.h>
00030 #include <cstring>
00031 #include <list>
00032 
00033 #include "error_desc.h"
00034 
00035 
00036 class BasicTcpServer
00037 {
00038   public:
00039       BasicTcpServer(int portNum, int maxClients=5, const char* intro=NULL); 
00046 
00047       virtual ~BasicTcpServer();
00048 
00049       void init();
00051 
00052       void blockOn();
00054 
00055       void setDebug(bool onOff) { debug = onOff; };
00057       
00058       static void setDebugAll(bool onOff) { debugAll = onOff; };
00060 
00061       void setID(const char* id) { this->id = id; };
00062 
00064       struct ClientInfo {
00065       int sockFd, port;
00066           time_t connectAt;
00067           char ip[16], host[31], user[12];
00068           pthread_t tid;
00069       ClientInfo(int sockFd, struct sockaddr_in* cliaddr) : sockFd(sockFd)
00070       {
00071               port = ntohs(cliaddr->sin_port);
00072               connectAt = time(NULL);
00073               sprintf(ip, "---.---.---.---");
00074               #ifdef SOLARIS
00075               strncpy(ip, inet_ntoa(cliaddr->sin_addr), 15);
00076               #else
00077               inet_ntop(AF_INET, &cliaddr->sin_addr, ip, sizeof(ip));
00078               #endif
00079               struct hostent* haddr;
00080               haddr = gethostbyaddr((const char*)&cliaddr->sin_addr, 
00081                         sizeof(cliaddr->sin_addr), AF_INET);
00082               strncpy(host, haddr->h_name, 30);
00083               sprintf(user, "unknown");
00084       };
00085           void setUser(const char* user)
00086           {
00087               strncpy(this->user, user, 11);
00088           };
00089           void print()
00090           {
00091               std::cout << "ClientInfo: " << ip << " " << host << " " << user << std::endl;
00092           };
00093       };      
00094       
00095   protected:
00096 
00097       pthread_attr_t threadAttr;
00098       struct sched_param threadParam;
00099       static const int SCHED_POLICY;
00100 
00101       char errMsg[120];
00102       
00103       int readn(int fd, char* buf, int nBytes, int timeOut);
00113       
00114       int readLine(int fd, char* buf, int maxBytes);
00125       
00126       virtual int doServerOp(ClientInfo* ci) = 0;
00133 
00134       virtual void onConnect(ClientInfo* curr);
00135 
00136       virtual void onDisconnect(ClientInfo* curr);
00137 
00138       const char* id;                 
00139       std::list<ClientInfo*> clientList;          
00140       std::list<ClientInfo*>::const_iterator pos; 
00141       pthread_mutex_t clientListMutex;            
00142 
00143   private:
00144       int port;
00145       int mClients;
00146       const char* intro;
00147       int nClients; 
00148       pthread_t serverThreadID; 
00149       char goAwayMsg[81];
00150       static bool debugAll;
00151       bool debug;
00152       
00153       // Structure passed as argument to threads.
00154       struct Arg {
00155          BasicTcpServer* obj;
00156          ClientInfo* ci;
00157          Arg(BasicTcpServer* obj, ClientInfo* ci=NULL) : 
00158              obj(obj), ci(ci) { };
00159       };      
00160 
00161       // Methods spawned as threads.  Must be static to conform
00162       // to signature specified by Posix Threads.
00163       static void* serverThread(void* arg);
00164       static void* clientHandlerThread(void* arg);
00165       static void* testThread(void* arg);
00166 
00167       // Disallow copy and assignment
00168       BasicTcpServer(const BasicTcpServer&);
00169       BasicTcpServer& operator=(const BasicTcpServer&);
00170 
00171 };
00172 
00173 
00174 #endif

Generated on Mon Apr 30 13:32:39 2007 for Parkes M & C - PKMC C++ library API by  doxygen 1.4.4