sprint 1-alpha
|
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