OSDN Git Service

windows/socket_impl2.hpp Add
authorMyun2 <myun2@nwhite.info>
Sat, 19 May 2012 05:27:47 +0000 (14:27 +0900)
committerMyun2 <myun2@nwhite.info>
Sat, 19 May 2012 05:27:47 +0000 (14:27 +0900)
roast/include/roast/windows/socket_impl2.hpp [new file with mode: 0644]

diff --git a/roast/include/roast/windows/socket_impl2.hpp b/roast/include/roast/windows/socket_impl2.hpp
new file mode 100644 (file)
index 0000000..4d6cb0c
--- /dev/null
@@ -0,0 +1,321 @@
+//     Roast+ License
+
+/*
+*/
+#ifndef __SFJP_ROAST__windows__net__socket_windows_impl_HPP__
+#define __SFJP_ROAST__windows__net__socket_windows_impl_HPP__
+
+#include <string>
+#include <ws2tcpip.h>
+#include <Wspiapi.h>
+#include <winsock2.h>
+#pragma comment(lib, "ws2_32.lib")
+                               
+//////////////////////////////////////////////////
+
+namespace roast
+{
+       class _socket_windows_impl_default_option
+       {
+       public:
+               static unsigned char GetWsockMajorVersion(){ return 2; }
+               static unsigned char GetWsockMinerVersion(){ return 0; }
+       };
+       
+       //////////////////////////////////////////////////////////////////////////////////////
+       
+       class _socket_windows_impl_constant
+       {
+       public:
+               typedef ::SOCKET socket_t;
+               static const socket_t invalid_socket;
+       };
+       const _socket_windows_impl_constant::socket_t _socket_windows_impl_constant::invalid_socket = INVALID_SOCKET;
+
+       ////////////////////
+       
+       class _socket_windows_instance_count
+       {
+       protected:
+               static int m_instance_count;
+       };
+       int _socket_windows_instance_count::m_instance_count = 0;
+
+       ////////////////////
+
+       template <typename _OptionT = _socket_windows_impl_default_option>
+               class socket_windows_impl_ : public _socket_windows_impl_constant, _socket_windows_instance_count
+       {
+       public:
+               typedef ::u_long in_addr_t;     //      Linux: in_addr_t
+               typedef struct ::sockaddr sockaddr_t;
+               typedef struct ::sockaddr_in sockaddr_in_t;
+               typedef struct ::addrinfo addrinfo_t;
+               typedef ::SOCKET socket_t;
+               //typedef ::fd_set fd_set_t, fdset_t;
+       
+       private:
+               //WSADATA* m_wsaInfo;
+               ::WSADATA* m_pWsaInfo;
+               int m_last_error;
+               ::std::string m_last_error_msg;
+               //static int m_instance_count;
+               
+               void _last_error_zero()
+               {
+                       m_last_error = 0;
+               }
+               void _WSAle_update()
+               {
+                       m_last_error = ::WSAGetLastError();
+               }
+               
+               bool _apiret_0true(int apiret)
+               {
+                       m_last_error = apiret;
+                       return ( apiret == 0 ? true : false );
+               }
+               
+               bool _apiret_WSAle(int apiret)
+               {
+                       _WSAle_update();
+                       return ( apiret == SOCKET_ERROR ? false : true );
+               }
+
+               int _myselect(socket_t s,
+                       ::fd_set *readfds, ::fd_set *writefds, ::fd_set *exceptfds,
+                       long timeout_sec, long timeout_usec)
+               {
+                       struct ::timeval tv;
+                       tv.tv_sec = timeout_sec;
+                       tv.tv_usec = timeout_usec;
+                       
+                       int ret = ::select(0/*Winsock always zero.*/, readfds, writefds, exceptfds, &tv);
+                       _WSAle_update();
+                       return ret;
+               }
+
+       public:
+               socket_windows_impl_()
+               {
+                       //ZeroMemory(&m_wsaInfo,sizeof(m_wsaInfo));
+                       m_pWsaInfo = NULL;
+                       m_last_error = 0;
+                       
+                       if ( m_instance_count == 0 )
+                               init();
+                       m_instance_count++;
+               }
+               virtual ~socket_windows_impl_()
+               {
+                       m_instance_count--;
+                       if ( m_instance_count == 0 )
+                               term();
+
+                       if ( m_pWsaInfo != NULL )
+                               delete m_pWsaInfo;
+               }
+               
+               ///////////////////////////////////////////////
+
+               //       init()
+               bool init()
+               {
+                       //ZeroMemory(m_wsaInfo,sizeof(m_wsaInfo));
+                       if ( m_pWsaInfo == NULL )
+                               m_pWsaInfo = new ::WSADATA();
+                       ZeroMemory(m_pWsaInfo,sizeof(::WSADATA));
+               
+                       WORD wVersionRequested = MAKEWORD(
+                               _OptionT::GetWsockMajorVersion(),
+                               _OptionT::GetWsockMinerVersion());
+               
+                       //return _apiret_0true( ::WSAStartup(wVersionRequested, &m_wsaInfo) );
+                       return _apiret_0true( ::WSAStartup(wVersionRequested, m_pWsaInfo) );
+               }
+               //WSADATA* get_wsadata(){ return &m_wsaInfo; }
+               ::WSADATA* get_wsadata(){ return m_pWsaInfo; }
+               
+               //       term()
+               bool term()
+               {
+                       return _apiret_0true( ::WSACleanup() );
+               }
+               
+               ///////////////////////////////////////////
+               
+               //      socket()
+               socket_t socket(int af, int type, int protocol)
+               {
+                       socket_t s = ::socket(af, type, protocol);
+                       _WSAle_update();
+                       return s;
+               }
+               
+               bool getaddrinfo(const char *node, const char *service,
+                       const addrinfo_t *hints, addrinfo_t **res)
+               {
+                       return _apiret_0true( ::getaddrinfo(node, service, hints, res) );
+               }
+               void freeaddrinfo(addrinfo_t *ai)
+               {
+                       ::freeaddrinfo(ai);
+               }
+               
+               int getnameinfo(const struct sockaddr *sa, socklen_t salen,
+                char *host, size_t hostlen,
+                char *serv, size_t servlen, int flags)
+        {
+               return _apiret_0true( ::getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) );
+        }
+
+               //      connect()
+               bool connect(socket_t s, const sockaddr_t *addr, int addrlen)
+               {
+                       return _apiret_WSAle( ::connect(s, addr, addrlen) );
+               }
+               
+               //      bind
+               bool bind(socket_t s, const sockaddr_t *addr, int len )
+               {
+                       return _apiret_WSAle( ::bind(s, addr, len) );
+               }
+
+               //      listen
+               bool listen(socket_t s, int max_queueing)
+               {
+                       return _apiret_WSAle( ::listen(s, max_queueing) );
+               }
+
+               //      accept
+               socket_t accept(socket_t s, sockaddr_t *addr_out, int *len_out )
+               {
+                       socket_t accepted_socket = ::accept(s, addr_out, len_out);
+                       _WSAle_update();
+                       return accepted_socket;
+               }
+               
+               //      shutdown()
+               //      \82±\82Ì\8aÖ\90\94\82Å\83\\83P\83b\83g\82Ì\91\97\90M\82©\8eó\90M\82ð\82Å\82«\82È\82­\82µ\82Ü\82·\81B
+               //      closesocket \8aÖ\90\94\82Å\83\\83P\83b\83g\82ð\95Â\82\82é\91O\82É\81A\82±\82Ì\8aÖ\90\94\82Å\90Ú\91±\82ð\92â\8e~\81i\83V\83\83\83b\83g\83_\83E\83\93\81j\82µ\82Ä\82­\82¾\82³\82¢\81B
+               /*
+                       WSAAsyncSelect \8aÖ\90\94\82ð\8eg\82Á\82Ä FD_CLOSE \92Ê\92m\82ð\93o\98^\82µ\82Ä\82­\82¾\82³\82¢\81
+                       shutdown \82Ì how \82É SD_SEND \82ð\93n\82µ\82Ä\82­\82¾\82³\82¢\81
+
+                       \93Á\82É\81AWindows Sockets \83v\83\8d\83o\83C\83_\82Í\81A\8eÕ\92f\82³\82ê\82½\83\\83P\83b\83g\82Ì connect \82Ì\8eg\97p\82É\91Î\89\9e\82·\82é\95K\97v\82Í\82 \82è\82Ü\82¹\82ñ\81
+               */
+               bool shutdown(socket_t s, int how=3)
+               {
+                       return _apiret_WSAle( ::shutdown(s, how) );
+               }
+
+               //      close()
+               bool close(socket_t s)
+               {
+                       return _apiret_WSAle( ::closesocket(s) );
+               }
+
+               /*
+               //      select()
+               int select(socket_t s,
+                       fdset_t *readfds, fdset_t *writefds, fdset_t *exceptfds,
+                       long timeout_sec, long timeout_usec)
+               {
+                       struct ::timeval tv;
+                       tv.tv_sec = timeout_sec;
+                       tv.tv_usec = timeout_usec;
+                       
+                       int ret = ::select(s, readfds, writefds, exceptfds, tv);
+                       _WSAle_update();
+                       return ret;
+               }
+               */
+               bool wait_readable(socket_t s, int timeout_ms)
+               {
+                       ::fd_set readfds;
+                       FD_ZERO(&readfds);
+                       FD_SET(s, &readfds);
+                                               
+                       int ret = _myselect(s, &readfds, NULL, NULL, timeout_ms/1000, timeout_ms*1000);
+                       _WSAle_update();
+                       //return FD_ISSET(m_socket, &readfds);
+                       return (ret > 0);
+               }
+               bool is_connected(socket_t s)
+               {
+                       ::fd_set readfds;
+                       FD_ZERO(&readfds);
+                       FD_SET(s, &readfds);
+                                               
+                       int ret = _myselect(s, &readfds, NULL, NULL, 0,0);
+                       _WSAle_update();
+                       //return FD_ISSET(m_socket, &readfds);
+                       return (ret != -1);
+               }
+
+               ////////////////////////////////////////////////////////////////
+
+               //      recv
+               //      \8ew\92è\82³\82ê\82½\83\\83P\83b\83g\83f\83B\83X\83N\83\8a\83v\83^\82ª\83X\83g\83\8a\81[\83\80\83\\83P\83b\83g\82Ì\8fê\8d\87\81A
+               //      \8aÖ\90\94\82Í\83o\83b\83t\83@\82É\8eó\90M\8dÏ\82Ý\83f\81[\83^\82ð\93ü\82ê\82ç\82ê\82é\82¾\82¯\93ü\82ê\81A
+               //      \8ec\82è\82Ì\83f\81[\83^\82Í\8e\9f\89ñ\82Ì\8cÄ\82Ñ\8fo\82µ\82Å\8eæ\93¾\82·\82é\8e\96\82ª\82Å\82«\82Ü\82·\81B
+               //      \83f\81[\83^\83O\83\89\83\80\83\\83P\83b\83g\82Ì\8fê\8d\87\82É\82Í\8eó\90M\82µ\82½\83f\81[\83^\83O\83\89\83\80\82Ì\82Å\82«\82é\82¾\82¯\91½\82­\82ð
+               //      \83o\83b\83t\83@\82É\95Û\91\82µ\82Ü\82·\82ª\81A\83o\83b\83t\83@\82É\93ü\82è\82«\82ç\82È\82©\82Á\82½\95ª\82Í\94j\8aü\82³\82ê\82Ü\82·\81B
+               //      \82±\82Ì\8e\9e\81A\8aÖ\90\94\82Í WSEMSGSIZE \83G\83\89\81[\82ð\94­\90\82µ\82Ü\82·\81B
+               //      \82±\82Ì\8aÖ\90\94\82Å\96â\91è\82ª\94­\90\82µ\82È\82¯\82ê\82Î\81A\8eó\90M\82µ\82½\83o\83C\83g\90\94\82ð\95Ô\82µ\82Ü\82·\81B
+               //      \90Ú\91±\82ª\90³\8fí\82É\95Â\82\82ç\82ê\82Ä\82¢\82½\8fê\8d\87\82Í\83[\83\8d\82ð\95Ô\82µ\82Ü\82·\81B
+               //      \83G\83\89\81[\82Í-1
+               int recv(socket_t s, void* buf, int len, int flag)
+               {
+                       int ret = ::recv(s, (char*)buf, len, flag);
+                       _WSAle_update();
+                       if ( ret == SOCKET_ERROR )
+                               return -1;
+                       return ret;
+               }
+
+               //      send()
+               //      \8aÖ\90\94\8cÄ\82Ñ\8fo\82µ\8cã\82·\82®\82É\83f\81[\83^\82ª\91\97\90M\82³\82ê\82é\82Æ\8c¾\82¤\95Û\8fØ\82Í\82 \82è\82Ü\82¹\82ñ\81B
+               //      \82à\82µ\91\97\90M\83o\83b\83t\83@\82ª\82¢\82Á\82Ï\82¢\82Å\81A\90V\82µ\82¢\83f\81[\83^\82ð\83o\83b\83t\83@\82É\95Û\91\82Å\82«\82È\82¢\8fê\8d\87\81A
+               //      \8aÖ\90\94\82Í\95Û\91\82ª\89Â\94\\82É\82È\82é\82Ü\82Å\8f\88\97\9d\82ð\92\86\92f\82µ\82Ü\82·\81B
+               //      \82±\82Ì\8aÖ\90\94\82Å\96â\91è\82ª\94­\90\82µ\82È\82¯\82ê\82Î\81A\91\97\90M\82µ\82½\91S\83o\83C\83g\90\94\82ð\95Ô\82µ\82Ü\82·\81B
+               //      \83G\83\89\81[\82Í-1
+               int send(socket_t s, const char* buf, int len, int flag)
+               {
+                       int ret = ::send(s, buf, len, flag);
+                       _WSAle_update();
+                       if ( ret == SOCKET_ERROR )
+                               return -1;
+                       return ret;
+               }
+
+               ////////////////////////////////////////////////////////////////////
+
+               int get_last_error(){ return m_last_error; }
+               const char* get_last_error_msg()
+               {
+                       m_last_error_msg = "";
+                       char *msg_buf;
+                       ::FormatMessageA(       FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
+                                                               NULL, m_last_error, LANG_USER_DEFAULT, (LPSTR)&msg_buf, 0, NULL );
+                       if ( msg_buf != NULL ){
+                               m_last_error_msg = msg_buf;
+                               LocalFree(msg_buf);
+                       }
+                       return m_last_error_msg.c_str();
+               }
+               
+               bool is_invalid_socket(::SOCKET s){
+                       return ( s == invalid_socket ? true : false );
+               }
+               bool is_valid_socket(::SOCKET s){
+                       return ( s == invalid_socket ? false : true );
+               }
+       };
+       typedef socket_windows_impl_<> socket_windows_impl;
+       
+       //static int m_instance_count = 0;
+}
+
+#endif//__SFJP_ROAST__windows__net__socket_windows_impl_HPP__