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

Socket.h

Go to the documentation of this file.
00001 /*  Socket.h - Winsock wrapper
00002     Copyright (C) 2001-2004 Mark Weaver
00003     Written by Mark Weaver <mark@npsl.co.uk>
00004 
00005     Part of the Open-Win32 library.
00006     This library is free software; you can redistribute it and/or
00007     modify it under the terms of the GNU Library General Public
00008     License as published by the Free Software Foundation; either
00009     version 2 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     Library General Public License for more details.
00015 
00016     You should have received a copy of the GNU Library General Public
00017     License along with this library; if not, write to the
00018     Free Software Foundation, Inc., 59 Temple Place - Suite 330,
00019     Boston, MA  02111-1307, USA.
00020 */
00021 
00026 #ifndef OW32_Socket_h
00027 #define OW32_Socket_h
00028 
00029 #include <OW32/OW32Libs.h>
00030 #include <OW32/SockAddrIn.h>
00031 
00032 // Open Win32 namespace
00033 namespace OW32
00034 {
00035 
00039 class OW32_LIB_EXPORT CSocket
00040 {
00041 public:
00042     CSocket() :
00043         m_socket(INVALID_SOCKET),
00044         m_timeout(-1)
00045     {
00046     }
00047 
00048     CSocket(int af, int type, int protocol) :
00049         m_socket(WSASocket(af, type, protocol, NULL, NULL, WSA_FLAG_OVERLAPPED)),
00050         m_timeout(-1)
00051     {
00052     }
00053 
00054     CSocket(SOCKET s) :
00055         m_socket(s),
00056         m_timeout(-1)
00057     {
00058     }
00059 
00060     virtual ~CSocket() 
00061     {
00062         if (m_socket != INVALID_SOCKET)
00063             ::closesocket(m_socket);
00064     }
00065 
00066     virtual int shutdown(int how) { return ::shutdown(m_socket, how); }
00067 
00068 #ifdef _MSC_VER
00069 #pragma warning(disable: 4127)
00070 #endif
00071 
00072     int wait_writeable() {
00073         fd_set  writefds;
00074         TIMEVAL timeout;
00075         timeout.tv_sec = (int)(m_timeout/10000000);
00076         timeout.tv_usec = (int)((m_timeout%10000000)/10);
00077 
00078         FD_ZERO(&writefds);
00079         FD_SET(m_socket, &writefds);
00080         int ret = select(1, NULL, &writefds, NULL, &timeout);
00081         if (ret == 0) { SetLastError(ERROR_TIMEOUT); return SOCKET_ERROR; }
00082         if (ret < 0) return SOCKET_ERROR;
00083         if (!FD_ISSET(m_socket, &writefds)) return SOCKET_ERROR;
00084         return 1;
00085     }
00086 
00087     int wait_readable() {
00088         fd_set readfds;
00089         TIMEVAL timeout;
00090         timeout.tv_sec = (int)(m_timeout/10000000);
00091         timeout.tv_usec = (int)((m_timeout%10000000)/10);
00092 
00093         FD_ZERO(&readfds);
00094         FD_SET(m_socket, &readfds);
00095         int ret = select(1,&readfds,NULL,NULL,&timeout);
00096         if (ret == 0) { SetLastError(ERROR_TIMEOUT); return SOCKET_ERROR; }
00097         if (ret < 0) return SOCKET_ERROR;
00098         if (!FD_ISSET(m_socket, &readfds)) return SOCKET_ERROR;
00099         return 1;
00100     }
00101 
00102 #ifdef _MSC_VER
00103 #pragma warning(default: 4127)
00104 #endif
00105 
00106     virtual int send(const char* buf, int len) {
00107         if (m_timeout!=-1) {
00108             int ret = wait_writeable();
00109             if (ret <= 0) return ret;
00110         }
00111         return ::send(m_socket, buf, len, 0);
00112     }
00113 
00114     virtual int recv(char* buf, int len) {
00115         if (m_timeout != -1) {
00116             int ret = wait_readable();
00117             if (ret <= 0) return ret;
00118         }
00119         return ::recv(m_socket, buf, len, 0);
00120     }
00121 
00122     void settimeout(__int64 timeout) {
00123         m_timeout = timeout;
00124     }
00125 
00126     __int64 gettimeout() {
00127         return m_timeout;
00128     }
00129 
00130     int bind(const struct sockaddr* name, int namelen) { return ::bind(m_socket, name, namelen); }
00131     int bind(CSockAddrIn& sockaddr_in) { return bind((const struct sockaddr *)&sockaddr_in, sizeof(sockaddr_in)); }
00132 
00133     virtual int close() { 
00134         SOCKET s = Detach();
00135         if (s == NULL || s == INVALID_SOCKET) {
00136             ::SetLastError(WSAENOTSOCK);
00137             return SOCKET_ERROR;
00138         }
00139         return ::closesocket(s);
00140     }
00141 
00142     virtual int connect(const struct sockaddr* name, int namelen) { return ::connect(m_socket, name, namelen); }
00143     virtual int connect(CSockAddrIn& sockaddr_in) { return connect((const struct sockaddr *)&sockaddr_in, sizeof(sockaddr_in)); }
00144 
00145     virtual int listen(int backlog=SOMAXCONN) { return ::listen(m_socket, backlog); }
00146     virtual SOCKET accept(sockaddr* addr, int* addrlen) { return ::accept(m_socket, addr, addrlen); }
00147     virtual SOCKET accept(CSockAddrIn& sockaddr_in) { int len=sizeof(sockaddr_in); return accept((struct sockaddr *)&sockaddr_in, &len); }
00148 
00149     // setsockopt for common option types
00150     int setopt(int optname, int value, int level=SOL_SOCKET)        { return ::setsockopt(m_socket, level, optname, (char*)&value, sizeof(value)); }
00151     int setopt(int optname, bool value, int level=SOL_SOCKET)       { return ::setsockopt(m_socket, level, optname, (char*)(BOOL*)&value, sizeof(value)); }
00152     int setopt(int optname, LINGER value, int level=SOL_SOCKET)     { return ::setsockopt(m_socket, level, optname, (char*)&value, sizeof(value)); }
00153     // generic setsockopt
00154     int setopt(int optname, char* pValue, int size, int level=SOL_SOCKET)       { return ::setsockopt(m_socket, level, optname, pValue, size); }
00155 
00156     // getsockopt for common option types
00157     int getopt(int optname, int* pValue, int level=SOL_SOCKET)      { int size=sizeof(int); return ::getsockopt(m_socket, level, optname, (char*)pValue, &size); }
00158     int getopt(int optname, bool* pValue, int level=SOL_SOCKET)     { int size=sizeof(int); return ::getsockopt(m_socket, level, optname, (char*)(BOOL*)pValue, &size); }
00159     int getopt(int optname, LINGER* pValue, int level=SOL_SOCKET)   { int size=sizeof(int); return ::getsockopt(m_socket, level, optname, (char*)pValue, &size); }
00160     // generic getsockopt
00161     int getopt(int optname, char* pValue, int* pSize, int level=SOL_SOCKET) { return ::getsockopt(m_socket, level, optname, pValue, pSize); }
00162 
00163     operator SOCKET() { return m_socket; }
00164     operator HANDLE() { return (HANDLE)(SOCKET)m_socket; }
00165 
00166     SOCKET Detach() { 
00167         SOCKET s = m_socket;
00168         m_socket = INVALID_SOCKET;
00169         return s;
00170     }
00171 
00172     void Attach(SOCKET s) { 
00173         if (m_socket != NULL && m_socket != INVALID_SOCKET)
00174             ::closesocket(m_socket);
00175         m_socket = s;
00176     }
00177 
00178 protected:
00180     SOCKET  m_socket;
00182     __int64 m_timeout;
00183 
00184 private:
00185     // No copy or assignment
00186     CSocket(const CSocket& );
00187     CSocket& operator= (const CSocket& );
00188 };
00189 
00190 } // namespace OW32
00191 
00192 #endif // OW32_Socket_h

Generated on Sun Jun 5 01:29:18 2005 for OW32 by  doxygen 1.3.9.1