sprint 1-alpha
sprint/io/network/socket.h
Go to the documentation of this file.
00001 /******************************************************************************
00002 *  Multi Platform Network Library
00003 *
00004 *   Copyright (C) 2005-2011  Paolo Medici <www.pmx.it>
00005 *
00006 *  This library is free software; you can redistribute it and/or
00007 *  modify it under the terms of the GNU Lesser General Public
00008 *  License as published by the Free Software Foundation; either
00009 *  version 2.1 of the License, or (at your option) any later version.
00010 *
00011 *  This library is distributed in the hope that it will be useful,
00012 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014 *  Lesser General Public License for more details.
00015 *
00016 *  You should have received a copy of the GNU Lesser General Public
00017 *  License along with this library; if not, write to the Free Software
00018 *  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00019 *
00020 *******************************************************************************/
00021 
00027 #ifndef _SPRINT_SOCKET_H
00028 #define _SPRINT_SOCKET_H
00029 
00030 #include <sprint/network_headers.h>
00031 
00032 #include <sprint/cpptraits.h>
00033 #include <sprint/io/network/nettools.h>
00034 
00035 namespace sprint {
00036 
00037 namespace detail {
00038 
00040 template<bool bManaged>
00041 class socket: public if_copiable<!bManaged> {
00042 protected:    
00043         SOCKET s;
00044 public:
00045 
00047         socket(SOCKET _s = INVALID_SOCKET) : s(_s) {}
00048 
00050         ~socket() { 
00051         if(bManaged) 
00052              close(); 
00053         }
00054 
00056         SOCKET handle() const { return s; }
00057 
00059         inline void shutdown() const { ::shutdown(s, SD_BOTH); }
00060         
00062         inline void close() { if(s!=INVALID_SOCKET) ::closesocket(s); s = INVALID_SOCKET; }
00064         inline bool is_valid() const { return s!=INVALID_SOCKET; }
00065 
00067         bool getsockname(sockaddr_in *target) const
00068         {
00069         int ret;
00070         socklen_t len = sizeof(sockaddr_in);
00071         ret = ::getsockname(s, (SOCKADDR *) target, &len);
00072         return ret==0;
00073         }
00074         
00076         bool getpeername(sockaddr_in *target) const
00077         {
00078         int ret;
00079         socklen_t len = sizeof(sockaddr_in);
00080         ret = ::getpeername(s, (SOCKADDR *) target, &len);
00081         return ret==0;
00082         }
00083         
00085         inline int listen(int backlog) const
00086         {
00087                 return ::listen(s, backlog);
00088         }
00089 
00091         bool set_ttl(int ttl)
00092         {
00093     if(::setsockopt(s,IPPROTO_IP,IP_MULTICAST_TTL, (LPCSTR) &ttl,sizeof(ttl))<0) 
00094          {
00095          // logPutsf(LOG_LEVEL_WARNING, "setsockopt: cannot set TTL = %u", ttl);      
00096      return false;
00097          }
00098     else
00099      return true;
00100     }
00101 
00103         bool connect(LPCSTR server_name, WORD port)
00104          {
00105          return sprint::socket_connect(s, server_name, port);
00106      }
00107 
00109         bool bind(WORD wPort)
00110         {
00111          return sprint::socket_bind(s, wPort);
00112      }
00113         
00116 
00117 
00118         SOCKET accept(sockaddr_in *paddr)
00119         {
00120         socklen_t len;
00121         len = sizeof(sockaddr_in);
00122         return ::accept(s, (struct sockaddr *) paddr, &len);
00123         }
00124   
00126     bool accept(socket<true> & target, sockaddr_in & addr)
00127     {
00128          return sprint::socket_accept(s, target.s, addr);
00129      }
00130  
00132         SOCKET accept(void)
00133         {
00134         sockaddr_in addr;
00135         return accept(&addr);   
00136         }
00139         #ifdef LINUX
00140 
00141         inline int ioctl(long cmd, void *argp) const
00142         {
00143                 return ::ioctl(s,cmd, argp);
00144         }
00145         #else
00146 
00147         inline int ioctl(long cmd, u_long *argp) const
00148         {
00149                 return ::ioctlsocket(s,cmd, argp);
00150         }
00151         #endif
00152 
00154         inline int write(const char *buf, unsigned int len) const
00155         {
00156          return (sprint::aff_write(s, buf, len)==0) ? int(len) : -1;
00157         }
00158 
00160         template<class T>
00161         inline int write(const T & item) const
00162                 {
00163                         return write((const char *)(&item), sizeof(item) );
00164                 }
00165 
00167         inline int send(const char *buf, unsigned int len) const
00168         {
00169                 return ::send(s, (const char *) buf, len, 0);
00170         }
00171 
00173         template<class T>
00174         inline int send(const T & item) const
00175                 {
00176                         return send((const char *)(&item), sizeof(item) );
00177                 }
00178 
00180         inline int read(char *buf, unsigned int len) const
00181         {
00182                 return ::recv(s, (char*) buf, len, 0 );
00183         }
00184 
00185 #ifdef WIN32
00186 
00187         inline int AsynchSelect(HWND hwnd, unsigned int wMsg, long lEvent)
00188         {
00189                 return ::WSAAsyncSelect(s, hwnd, wMsg, lEvent);
00190         }
00192         inline int EventSelect(WSAEVENT hEventObject,   long lNetworkEvents)
00193         {
00194         return ::WSAEventSelect(s, hEventObject, lNetworkEvents);       
00195     }
00196 #endif
00197 
00198 };
00199 
00201 template<bool bManaged>
00202 class udp_socket: public socket<bManaged> {
00203 public:
00204         udp_socket() : socket<bManaged>(::socket(AF_INET, SOCK_DGRAM, 0)) { }
00205         udp_socket(SOCKET _s) : socket<bManaged>(_s) {}
00206 
00207         template<bool T>
00208         udp_socket(const udp_socket<T> & s) : socket<bManaged>(s.handle()) {}   
00209 
00210 };
00211 
00213 template<bool bManaged>
00214 class multicast_socket: public udp_socket<bManaged> {
00215         struct ip_mreq mreq;
00216 public:
00217         bool add_membership(LPCSTR mcastgroup)
00218         {
00219         return sprint::mcast_add_membership(this->s, mcastgroup, &mreq);         
00220         }
00221         bool drop_membership()
00222         {
00223         return sprint::mcast_drop_membership(this->s, &mreq);
00224         }
00225 };
00226 
00228 template<bool bManaged>
00229 class tcp_socket: public socket<bManaged> {
00230 public:
00231         tcp_socket() : socket<bManaged>( ::socket(AF_INET, SOCK_STREAM, 0) ) { }
00232         tcp_socket(SOCKET _s) : socket<bManaged>(_s) {}
00233 
00234         template<bool T>
00235         tcp_socket(const tcp_socket<T> & s) : socket<bManaged>(s.handle()) {}   
00236 
00237 };
00238 
00239 } // namespace detail
00240 
00242 typedef detail::socket<true>  socket;
00243 
00245 typedef detail::socket<false> socket_handle;
00246 
00248 typedef detail::udp_socket<true>  udp_socket;
00249 
00250 typedef detail::udp_socket<false> udp_socket_handle;
00251 
00253 typedef detail::tcp_socket<true>  tcp_socket;
00254 
00255 typedef detail::tcp_socket<false> tcp_socket_handle;
00256 
00257 }; // namespace sprint
00258 
00259 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Defines