Main Page   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members   Related Pages  

socketinstance.h

Go to the documentation of this file.
00001 /********************************************************************
00002         Copyright (c) 2001, Lee Patterson & Ant Works Software
00003         http://ssobjects.sourceforge.net
00004 
00005         Original source from Inside Visual C++
00006 
00007         created  :  5/14/1998
00008         filename :  socketinstance.h
00009         author   :  Lee Patterson (lee@antws.com)
00010         
00011         purpose  :  Base socket class. Also http and telnet 
00012                     classes. Defaults to blocking mode.
00013 
00014         notes    :  Typical client session would look like this:
00015                     
00016                     ...
00017                     SocketInstance sConnection;
00018                     try
00019                     {
00020                         //open connection
00021                         puts("Connecting to server...");
00022                         SockAddr saServer(szHost,iPort);
00023                         if(isalpha(szHost[0]))  //check if szHost is in "host.com" format or "255.255.255.255"
00024                             saServer = SocketInstance::getHostByName(szHost,iPort);
00025                         sConnection.create();
00026                         sConnection.connect(saServer);
00027                         //we are connected, so some transfering
00028                         ...
00029                         sConnection.close();
00030                     }
00031                     catch(GeneralException* e)
00032                     {
00033                         sConnection.cleanup();
00034                         LOG("error %s",e->getErrorMsg());
00035                     }
00036                     ...
00037                     
00038                     A server would look like this:
00039                     
00040                     ...
00041                     SocketInstance sClient;
00042                     SockAddr saClient;
00043                     SockAddr saServer(INADDR_ANY,atoi(argv[1]));
00044                     SocketInstance sListen;
00045                     try
00046                     {
00047                         sListen.create();
00048                         sListen.bind(saServer);
00049                         sListen.listen();
00050                         while(bWantMoreConnections)
00051                         {
00052                             sListen.accept(sClient,saClient);
00053                             //we got a connection ...
00054                             sClient.close();
00055                         }
00056                         sListen.close();
00057                     }
00058                     catch(GeneralException* e)
00059                     {
00060                         sConnection.cleanup();
00061                         LOG("error %s",e->getErrorMsg());
00062                     }
00063                     ...
00064                     
00065                     
00066 
00067 *********************************************************************/
00068 
00069 #ifndef SOCKETINSTANCE_H
00070 #define SOCKETINSTANCE_H
00071 
00072 #ifdef OS_LINUX
00073 #define USE_POLL
00074 #endif
00075 
00076 #define __SockAddr__
00077 #define __SocketInstance__
00078 #define __SocketInstanceException__
00079 #define __TelnetSocket__
00080 #define __HttpBlockingSocket__
00081 
00082 #ifdef WIN32
00083 #include <winsock.h>
00084 #endif
00085 
00086 #include <sys/types.h>
00087 #include <ctype.h>
00088 #include "msdefs.h"
00089 #include <stdio.h>
00090 
00091 #ifndef WIN32
00092 # include <netinet/in.h>
00093 # include <netdb.h>
00094 # ifndef USE_POLL
00095 #   include <sys/select.h>    //not using select, using poll instead as select gave me some headaches
00096 # else
00097 #   include <sys/poll.h>
00098 # endif
00099 # include <arpa/inet.h>
00100 # include <sys/time.h>
00101 # include <sys/types.h>
00102 # include <sys/socket.h>
00103 # include <unistd.h>
00104 #endif
00105 
00106 #include <stdio.h>
00107 #include <stdlib.h>
00108 #include "generalexception.h"
00109 #include "errno.h"
00110 
00111 enum {
00112     DEFAULT_SOCKET_TIMEOUT=600,     //10 minutes
00113     NO_TIMEOUT=0,                   //never time out    
00114 };
00115 
00116 #define TELNET_PORT         23
00117 #define WEB_PORT            80
00118 
00119 #ifndef WIN32
00120 # define WSAEWOULDBLOCK       EWOULDBLOCK
00121 # define SOCKET_ERROR        (-1)
00122 # define INVALID_SOCKET      (-1)
00123 # define closesocket(s)      close(s)
00124 # define WSAGetLastError()   errno
00125 
00126 typedef int SOCKET;
00127 typedef struct sockaddr        SOCKADDR;
00128 
00129 typedef struct sockaddr_in     SOCKADDR_IN;
00130 typedef struct sockaddr_in*    LPSOCKADDR_IN;
00131 #endif
00132 
00133 #ifdef WIN32
00134   typedef int socklen_t;
00135 #endif
00136 
00137 typedef struct timeval  TIMEVAL;
00138 typedef unsigned long   ULONG;
00139 typedef unsigned short  USHORT;
00140 
00141 typedef const struct sockaddr* LPCSOCKADDR;
00142 typedef struct sockaddr*       LPSOCKADDR;
00143 
00144 namespace ssobjects
00145 {
00146 
00147 
00148 
00149 // member functions truly block and must not be used in UI threads
00150 // use this class as an alternative to the MFC CSocket class
00151 
00152 #ifdef __SocketInstanceException__
00153 #define throwSocketInstanceException(m) (throw SocketInstanceException(m,__FILE__,__LINE__))
00154 
00161 class SocketInstanceException : public GeneralException
00162 {
00163 public:
00164     SocketInstanceException(const char* pchMessage,const char* pFname,const int iLine) : GeneralException(pchMessage,pFname,iLine){}
00165     ~SocketInstanceException(){}
00166 };
00167 #endif
00168 
00169 #ifdef __SocketInstance__
00170 class SockAddr;
00171 
00234 class SocketInstance 
00235 {
00236   public:
00237     SOCKET m_hSocket;
00238     bool   m_bThrowExceptionOnReadClose;
00239     SocketInstance() : m_hSocket(0),m_bThrowExceptionOnReadClose(true) {}
00240     SOCKET getSocket() const {return m_hSocket;}
00241     void setExceptionOnReadClose(const bool bThrowException=true);  
00242     void cleanup();
00243     void create(const int nType = SOCK_STREAM);
00244     void close();
00245     void bind(LPCSOCKADDR psa);
00246     void listen();
00247     void connect(LPCSOCKADDR psa);
00248     bool accept(SocketInstance& s, LPSOCKADDR psa);
00249     bool accept(SocketInstance* s, LPSOCKADDR psa);
00250     int send(const char* pch, const int nSize, const int nSecs=DEFAULT_SOCKET_TIMEOUT);
00251     int write(const char* pch, const int nSize, const int nSecs=DEFAULT_SOCKET_TIMEOUT);
00252     int recv(char* pch, const int nSize, const int nSecs=DEFAULT_SOCKET_TIMEOUT);
00253     int sendDatagram(const char* pch, const int nSize, LPCSOCKADDR psa, 
00254                      const int nSecs=10);
00255     int receiveDatagram(char* pch, const int nSize, LPSOCKADDR psa, 
00256                         const int nSecs=10);
00257     void getPeerAddr(LPSOCKADDR psa);
00258     void getSockAddr(LPSOCKADDR psa);
00259     static SockAddr getHostByName(const char* pchName, 
00260                                     const USHORT ushPort = 0);
00261     static const char* getHostByAddr(LPCSOCKADDR psa);
00262     operator SOCKET()
00263     { return m_hSocket; }
00264     
00265     SocketInstance& operator=(const SocketInstance& s);
00266     SocketInstance(const SocketInstance& s) : m_hSocket(s.m_hSocket),m_bThrowExceptionOnReadClose(s.m_bThrowExceptionOnReadClose) {}
00267 };
00268 #endif
00269 
00270 #ifdef __SockAddr__
00271 
00277 class SockAddr : public sockaddr_in 
00278 {
00279   public:
00280     // constructors
00281     SockAddr()
00282     { sin_family = AF_INET;
00283     sin_port = 0;
00284     sin_addr.s_addr = 0; } // Default
00285     SockAddr(const sockaddr& sa) { memcpy(this, &sa, sizeof(SOCKADDR)); }
00286     SockAddr(const sockaddr_in& sin) { memcpy(this, &sin, sizeof(SOCKADDR_IN)); }
00287     SockAddr(const ULONG ulAddr, const USHORT ushPort = 0) // parms are host byte ordered
00288     { sin_family = AF_INET;
00289     sin_port = htons(ushPort);
00290     sin_addr.s_addr = htonl(ulAddr); }
00291 #ifdef OS_LINUX
00292     SockAddr(const uint32_t ulAddr, const USHORT ushPort = 0) // parms are host byte ordered
00293     { sin_family = AF_INET;
00294     sin_port = htons(ushPort);
00295     sin_addr.s_addr = htonl(ulAddr); }
00296 #endif
00297     SockAddr(const char* pchIP, const USHORT ushPort = 0) // dotted IP addr string
00298     { 
00299       if(isalpha(pchIP[0])) //check if IP is in "host.com" format or "255.255.255.255"
00300       {
00301         struct hostent* pHostEnt = gethostbyname(pchIP);
00302         if(pHostEnt == NULL) {
00303           CStr s;
00304           int err = WSAGetLastError();
00305           strerror(err);
00306           s.format("SockAddr GetHostByName error %d:%s",err,strerror(err));
00307       
00308           throwSocketInstanceException((const char*)s);
00309         }
00310         ULONG* pulAddr = (ULONG*) pHostEnt->h_addr_list[0];
00311         sin_family = AF_INET;
00312         sin_port = htons(ushPort);
00313         sin_addr.s_addr = *pulAddr; // address is already in network byte order
00314                 
00315       }
00316       else
00317       {
00318         sin_family = AF_INET;
00319         sin_port = htons(ushPort);
00320         sin_addr.s_addr = inet_addr(pchIP); 
00321       }
00322     } // already network byte ordered
00323     // Return the address in dotted-decimal format
00324     char* dottedDecimal()
00325     { return inet_ntoa(sin_addr); }
00326     // Get port and address (even though they're public)
00327     USHORT port() const
00328     { return ntohs(sin_port); }
00329     ULONG ipAddr() const
00330     { return ntohl(sin_addr.s_addr); }
00331     // operators added for efficiency
00332     const SockAddr& operator=(const SOCKADDR& sa)
00333     { memcpy(this, &sa, sizeof(SOCKADDR));
00334     return *this; }
00335     const SockAddr& operator=(const SOCKADDR_IN& sin)
00336     { memcpy(this, &sin, sizeof(SOCKADDR_IN));
00337     return *this; }
00338     operator SOCKADDR()
00339     { return *((LPSOCKADDR) this); }
00340     operator LPSOCKADDR()
00341     { return (LPSOCKADDR) this; }
00342     operator LPSOCKADDR_IN()
00343     { return (LPSOCKADDR_IN) this; }
00344     bool operator == (const sockaddr_in& sa);     
00345 };
00346 #endif
00347 
00348 
00349 #ifdef __TelnetSocket__
00350 class TelnetSocket : public SocketInstance
00351 {
00352   public:
00353     enum {nSizeRecv = 1024}; // max receive buffer size (> hdr line length)
00354     enum {FLAG_VALIDATED=1,FLAG_PLAYING=2};
00355     TelnetSocket();
00356     TelnetSocket(SocketInstance& s);
00357     TelnetSocket(SocketInstance* s);
00358     virtual ~TelnetSocket();
00359     int readLine(char* pch, const int nSize, const int nSecs=DEFAULT_SOCKET_TIMEOUT);
00360     int readResponse(char* pch, const int nSize, const int nSecs=DEFAULT_SOCKET_TIMEOUT);
00361     int println(const char* fmt,...);
00362     int print(const char* fmt,...);
00363     bool setLoginName(const char* name);
00364 
00365   public:
00366     //login information
00367     char* m_pLoginName;
00368     WORD m_wFlags;
00369 
00370   private:
00371     char* m_pReadBuf; // read buffer
00372     int m_nReadBuf; // number of bytes in the read buffer
00373 
00374   private:
00375     TelnetSocket(const TelnetSocket&);
00376     TelnetSocket& operator=(const TelnetSocket&);
00377 };
00378 #endif
00379 
00380 #ifdef __HttpBlockingSocket__
00381 class HttpBlockingSocket : public SocketInstance
00382 {
00383   public:
00384     enum {nSizeRecv = 1000}; // max receive buffer size (> hdr line length)
00385     HttpBlockingSocket();
00386     ~HttpBlockingSocket();
00387     int readHttpHeaderLine(char* pch, const int nSize, const int nSecs);
00388     int readHttpResponse(char* pch, const int nSize, const int nSecs);
00389   private:
00390     char* m_pReadBuf; // read buffer
00391     int m_nReadBuf; // number of bytes in the read buffer
00392   private:
00393     //unused overloads
00394     HttpBlockingSocket(const HttpBlockingSocket&);
00395     HttpBlockingSocket& operator=(const HttpBlockingSocket&);
00396 };
00397 #endif
00398 
00399 };
00400 
00401 #endif
00402 

Generated on Thu Nov 8 12:39:26 2001 for SimpleServerObjects by doxygen1.2.11 written by Dimitri van Heesch, © 1997-2001