00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
00154 int setopt(int optname, char* pValue, int size, int level=SOL_SOCKET) { return ::setsockopt(m_socket, level, optname, pValue, size); }
00155
00156
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
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
00186 CSocket(const CSocket& );
00187 CSocket& operator= (const CSocket& );
00188 };
00189
00190 }
00191
00192 #endif // OW32_Socket_h