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

sstuff.hh

00001 #include <string>
00002 #include <sstream>
00003 #include <iostream>
00004 #include <errno.h>
00005 #include <sys/types.h>
00006 #include <unistd.h>
00007 #include <sys/socket.h>
00008 #include <netinet/in.h>
00009 #include <arpa/inet.h>
00010 #include <sys/select.h>
00011 #include <fcntl.h>
00012 
00013 using namespace std;
00014 
00015 
00016 typedef string NetworkError;
00017 
00019 class IPAddress
00020 {
00021 public:
00022   u_int32_t byte; 
00023 
00025   IPAddress()
00026   {
00027     byte=0;
00028   }
00030   IPAddress(const string &remote)
00031   {
00032     struct in_addr addr;
00033     if(!inet_aton(remote.c_str(), &addr))
00034       throw NetworkError("Could not convert '"+remote+"' to an IP address");
00035     byte=addr.s_addr;
00036   }
00037 
00039   string asString() const
00040   {
00041     ostringstream o;
00042     const unsigned char *n=reinterpret_cast<const unsigned char*>(&byte);
00043     o<<(unsigned int)*n++<<".";
00044     o<<(unsigned int)*n++<<".";
00045     o<<(unsigned int)*n++<<".";
00046     o<<(int)*n++;
00047     return o.str();
00048   }
00049 };
00050 
00051 typedef u_int16_t IPPort;
00052 
00054 class IPEndpoint
00055 {
00056 public:
00057 
00058   IPEndpoint(){}   
00059   IPEndpoint(const string &remote, IPPort aport=0) : address(remote), port(aport){} 
00060   IPAddress address;
00061   IPPort port;
00062   enum PortTypes {ANY=0};
00063 };
00064 
00065 
00066 enum AddressFamily {InterNetwork=AF_INET}; 
00067 enum SocketType {Datagram=SOCK_DGRAM,Stream=SOCK_STREAM}; 
00068 typedef int ProtocolType; 
00069 
00071 class Socket
00072 {
00073 private:
00074   Socket(const Socket &);
00075   Socket &operator=(const Socket &);
00076 
00077   Socket(int fd)
00078   {
00079     d_buflen=1024;
00080     d_buffer=new char[d_buflen];
00081     d_socket=fd;
00082   }
00083 public:
00085   Socket(AddressFamily af, SocketType st, ProtocolType pt=0)
00086   {
00087     d_family=af;
00088     if((d_socket=socket(af,st, pt))<0)
00089       throw NetworkError(strerror(errno));
00090     d_buflen=1024;
00091     d_buffer=new char[d_buflen];
00092   }
00093 
00094   ~Socket()
00095   {
00096     close(d_socket);
00097     delete[] d_buffer;
00098   }
00099 
00101   Socket *accept()
00102   {
00103     struct sockaddr_in remote;
00104     socklen_t remlen=sizeof(remote);
00105     int s=::accept(d_socket,(sockaddr *)&remote, &remlen);
00106     if(s<0) {
00107       if(errno==EAGAIN)
00108         return 0;
00109 
00110       throw NetworkError("Accepting a connection: "+string(strerror(errno)));
00111     }
00112     return new Socket(s);
00113   }
00114 
00116   void setNonBlocking()
00117   {
00118     int flags=fcntl(d_socket,F_GETFL,0);    
00119     if(flags<0 || fcntl(d_socket, F_SETFL,flags|O_NONBLOCK) <0)
00120       throw NetworkError("Setting socket to nonblocking: "+string(strerror(errno)));
00121   }
00122 
00124   void bind(const IPEndpoint &ep)
00125   {
00126     struct sockaddr_in local;
00127     memset(reinterpret_cast<char *>(&local),0,sizeof(local));
00128     local.sin_family=d_family;
00129     local.sin_addr.s_addr=ep.address.byte;
00130     local.sin_port=htons(ep.port);
00131     
00132     int tmp=1;
00133     if(setsockopt(d_socket,SOL_SOCKET,SO_REUSEADDR,(char*)&tmp,sizeof tmp)<0)
00134       throw NetworkError(string("Setsockopt failed: ")+strerror(errno));
00135 
00136     if(::bind(d_socket,(struct sockaddr *)&local,sizeof(local))<0)
00137       throw NetworkError(strerror(errno));
00138   }
00139 
00141 
00144   void recvFrom(string &dgram, IPEndpoint &ep)
00145   {
00146     struct sockaddr_in remote;
00147     socklen_t remlen=sizeof(remote);
00148     int bytes;
00149     if((bytes=recvfrom(d_socket, d_buffer, d_buflen, 0, (sockaddr *)&remote, &remlen))<0)
00150       throw NetworkError(strerror(errno));
00151     
00152     dgram.assign(d_buffer,bytes);
00153     ep.address.byte=remote.sin_addr.s_addr;
00154     ep.port=ntohs(remote.sin_port);
00155   }
00156 
00158 
00161   void sendTo(const string &dgram, const IPEndpoint &ep)
00162   {
00163     struct sockaddr_in remote;
00164     remote.sin_family=d_family;
00165     remote.sin_addr.s_addr=ep.address.byte;
00166     remote.sin_port=ntohs(ep.port);
00167 
00168     if(sendto(d_socket, dgram.c_str(), dgram.size(), 0, (sockaddr *)&remote, sizeof(remote))<0)
00169       throw NetworkError(strerror(errno));
00170   }
00171 
00173   void writen(const string &data)
00174   {
00175     int toWrite=data.length();
00176     int res;
00177     const char *ptr=data.c_str();
00178     do {
00179       res=::write(d_socket,ptr,toWrite);
00180       if(res<0) 
00181         throw NetworkError("Writing to a socket: "+string(strerror(errno)));
00182       toWrite-=res;
00183     }while(toWrite);
00184   }
00185 
00187 
00191   unsigned int tryWrite(const char *ptr, int toWrite)
00192   {
00193     int res;
00194     res=::write(d_socket,ptr,toWrite);
00195     if(res==0)
00196       throw NetworkError("EOF on writing to a socket");
00197 
00198     if(res>0)
00199       return res;
00200 
00201     if(errno==EAGAIN)
00202       return 0;
00203     
00204     throw NetworkError("Writing to a socket: "+string(strerror(errno)));
00205   }
00206 
00208 
00209   unsigned int write(const char *ptr, int toWrite)
00210   {
00211     int res;
00212     res=::write(d_socket,ptr,toWrite);
00213     if(res<0) {
00214       throw NetworkError("Writing to a socket: "+string(strerror(errno)));
00215     }
00216     return res;
00217   }
00218 
00219 
00221   int getchar()
00222   {
00223     char c;
00224 
00225     int res=::read(d_socket,&c,1);
00226     if(res)
00227       return c;
00228     return -1;
00229   }
00230 
00232   void read(string &data)
00233   {
00234     int res=::read(d_socket,d_buffer,d_buflen);
00235     if(res<0) 
00236       throw NetworkError("Reading from a socket: "+string(strerror(errno)));
00237     data.assign(d_buffer,res);
00238   }
00239 
00241   int read(char *buffer, int bytes)
00242   {
00243     int res=::read(d_socket,buffer,bytes);
00244     if(res<0) 
00245       throw NetworkError("Reading from a socket: "+string(strerror(errno)));
00246     return res;
00247 
00248   }
00249 
00251   void listen(unsigned int length=10)
00252   {
00253     if(::listen(d_socket,length)<0)
00254       throw NetworkError("Setting socket to listen: "+string(strerror(errno)));
00255   }
00256 
00258   int getHandle() const
00259   {
00260     return d_socket;
00261   }
00262   
00263 private:
00264   int d_socket;
00265   char *d_buffer;
00266   int d_buflen;
00267   int d_family;
00268 };
00269 
00271 class UDPListener
00272 {
00273 public:
00275   UDPListener(const IPEndpoint &ep)
00276   {
00277     d_ep=ep;
00278     initSocket();
00279   }
00281   UDPListener(IPPort port)
00282   {
00283     d_ep.address.byte=0; // =IPAddress::ANY;
00284     d_ep.port=port;
00285     initSocket();
00286   }
00288   UDPListener()
00289   {
00290     d_ep.address.byte=0; // =IPEndpoint::ANY;
00291     d_ep.port=0;
00292     initSocket();
00293   }
00294   ~UDPListener()
00295   {
00296     delete d_socket;
00297   }
00299   void recvFrom(string &dgram, IPEndpoint &remote)
00300   {
00301     d_socket->recvFrom(dgram,remote);
00302   }
00303 
00305   void sendTo(const string &dgram, const IPEndpoint &remote)
00306   {
00307     d_socket->sendTo(dgram,remote);
00308   }
00309 
00310 private:
00311   void initSocket()
00312   {
00313     d_socket=new Socket(InterNetwork, Datagram);
00314     d_socket->bind(d_ep);
00315   }
00316 
00317 
00318 
00319 private:
00320   UDPListener(const UDPListener &);
00321   UDPListener &operator=(const UDPListener &);
00322   IPEndpoint d_ep;
00323   Socket *d_socket;
00324 
00325 };

Generated on Sun Feb 8 12:07:52 2004 for MTasker by doxygen 1.3.5