TX Library Help – Version: 00173a, Revision: 174
 ALL  Windows graphics in a sandbox

TXNetwork.h

См. документацию.
00001 //{=============================================================================
00002 //  Библиотека TXNetwork - TXNetwork.h
00003 //  Copyright (C) Vova Yurovsky, 7 класс - Source code
00004 //                Vova Yurovsky, 8 класс - Help
00005 //}=============================================================================
00006 
00007 //{================================DOXYGEN======================================
00010 //  @mainpage
00087 //}=============================================================================
00088 
00089 #ifndef TXN_H
00090 #define TXN_H
00091 
00092 //{
00093 #pragma GCC diagnostic push
00094 #pragma GCC diagnostic ignored "-Wswitch-enum"
00095 #pragma GCC diagnostic ignored "-Wmissing-field-initializers"
00096 #pragma GCC diagnostic ignored "-Wsign-conversion"
00097 //}
00098 
00099 //{ Includes (##-INTERNAL-##)
00101 
00102 #ifdef __TXLIB_H_INCLUDED
00103 
00104 #error -----------------------------------------------------------------------
00105 #error Do not include TXLib before TXNetwork.
00106 #error -----------------------------------------------------------------------
00107 
00108 #endif
00109 
00110 #ifndef WINVER
00111 
00112 #define WINVER 0x0501
00113 
00114 #endif
00115 
00116 #ifndef _WIN32_IE
00117 
00118 #define _WIN32_IE WINVER
00119 
00120 #endif
00121 
00122 #if (WINVER < 0x0501)
00123 
00124 #error -------------------------------------------------------------------------
00125 #error TXNetwork requires WINVER 0x0501 or above. To define WINVER:
00126 #error #define WINVER MEOW
00127 #error #define MEOW   0x0501
00128 #error -------------------------------------------------------------------------
00129 
00130 #endif
00131 
00132 #if (_WIN32_IE < 0x0501)
00133 
00134 #error -------------------------------------------------------------------------
00135 #error TXNetwork requires _WIN32_IE 0x0501 or above. To define _WIN32_IE:
00136 #error #define _WIN32_IE CAT
00137 #error #define CAT   0x0501
00138 #error -------------------------------------------------------------------------
00139 
00140 #endif
00141 
00142 #pragma GCC system_header
00143 
00144 #undef  __STRICT_ANSI__
00145 
00146 #include <ws2tcpip.h>
00147 #include <stdio.h>
00148 #include <assert.h>
00149 
00151 //}
00152 
00153 //{ defines, typedefs
00154 
00159 
00160 #define TX_BROADCAST    "255.255.255.255"
00161 #define TX_BROADCAT      TX_BROADCAST       // For compatibility with other cats. ^^ :)
00162 
00167 
00168 #define TX_STD_PORT     27050
00169 
00174 
00175 #define TX_LOCALHOST    "127.0.0.1"
00176 
00181 
00182 #define TXN_NOT_CREATED 101
00183 
00188 
00189 #define TXN_OK          100
00190 
00195 
00196 #define TXN_ERROR       -1
00197 
00200 
00201 enum sock_type
00202     {
00203     TX_SERVER   =  1,  
00204     TX_CLIENT   =  2,  
00205     TX_BLOCK    =  3,  
00206     TX_NONBLOCK =  4,  
00207     TX_NOTYPE   = -1   
00208     };
00210 
00217 
00218 //}
00219 
00220 // The Classes
00221 //{
00222 
00224 
00225 class txSmartSocket_
00226 {
00227 SOCKET sock;
00228 unsigned int num_of_ref;
00229 
00230 txSmartSocket_ (const txSmartSocket_& var) = delete;
00231 txSmartSocket_& operator= (txSmartSocket_& what) = delete;
00232 
00233 public:
00234     txSmartSocket_ ():
00235     sock(INVALID_SOCKET),
00236     num_of_ref(0)
00237     {}
00238 
00239     txSmartSocket_ (SOCKET var):
00240     sock (var),
00241     num_of_ref (1)
00242     {}
00243 
00244     txSmartSocket_ (txSmartSocket_&& var):
00245     sock(var.sock),
00246     num_of_ref(var.num_of_ref)
00247     {
00248     var.sock = NULL;
00249     var.num_of_ref = 0;
00250     }
00251 
00252     ~txSmartSocket_()
00253     {
00254     if (sock);
00255         closesocket(sock);
00256     }
00257 
00258 SOCKET& operator*();
00259 
00260 txSmartSocket_* Create();
00261 txSmartSocket_* Delete();
00262 };
00263 
00265 
00266 class TX_SOCKET
00267     {
00269 
00270     bool      _broadcats;  // ^_^
00271     bool      _TCP;
00272     bool      _init;
00273     sock_type _type;
00274 
00275     txSmartSocket_* _sock;
00276     sockaddr_in _sock_addr;
00277 
00278     txSmartSocket_* _client_sock_for_serv;
00279     sockaddr_in _client_addr;
00280 
00281     sock_type _type_;
00282 
00283     bool _txInitAsServer (const char*,    u_short port, sock_type type, bool useTCP, const unsigned OueueSize);
00284     bool _txInitAsClient (const char* IP, u_short port, sock_type type, bool useTCP, const unsigned);
00285 
00286     public:
00287 
00288     TX_SOCKET():
00289         _broadcats(),
00290         _TCP (true),
00291         _init (false),
00292         _type (TX_NOTYPE),
00293         _sock(),
00294         _sock_addr(),
00295         _client_sock_for_serv(),
00296         _client_addr(),
00297         _type_ (TX_BLOCK)
00298         {}
00299 
00300     TX_SOCKET (const TX_SOCKET& that):
00301         _broadcats (that._broadcats),
00302         _TCP (that._TCP),
00303         _init (that._init),
00304         _type (that._type),
00305         _sock (_init? that._sock -> Create() : NULL),
00306         _sock_addr (that._sock_addr),
00307         _client_sock_for_serv (that._client_sock_for_serv? that._client_sock_for_serv -> Create() : NULL),
00308         _client_addr (that._client_addr),
00309         _type_ (that._type_)
00310         {}
00311 
00312     TX_SOCKET (sock_type type, const char* IP, int port, sock_type blocking, bool useTCP, const unsigned OueueSize):
00313         _broadcats(),
00314         _TCP (useTCP),
00315         _init (false),
00316         _type (type),
00317         _sock (0),
00318         _sock_addr(),
00319         _client_sock_for_serv(),
00320         _client_addr(),
00321         _type_ (blocking)
00322         {
00323         if (IP == NULL)
00324             {
00325             if (type == TX_SERVER)
00326                 _broadcats = false;
00327             else
00328                 return;
00329             }
00330         else
00331             {
00332             assert (IP);
00333             _broadcats = ! (strcmp (IP, TX_BROADCAST));          // TX_BROADCAT :)
00334             }
00335 
00336         switch (_type)
00337             {
00338             case TX_CLIENT:   if (! (this->*(_broadcats? &TX_SOCKET :: _txInitAsServer : &TX_SOCKET :: _txInitAsClient))
00339                                     (IP, (u_short) port, _type_, useTCP, OueueSize)) return;
00340                               break;
00341 
00342             case TX_SERVER:   if (! (this->*(_broadcats? &TX_SOCKET :: _txInitAsClient : &TX_SOCKET :: _txInitAsServer))
00343                                     (IP, (u_short) port, _type_, useTCP, OueueSize)) return;
00344                               break;
00345 
00346             case TX_BLOCK:
00347             case TX_NONBLOCK: return;
00348 
00349             case TX_NOTYPE:   break;
00350 
00351             default:          break;
00352             }
00353 
00354         _init = true;
00355         }
00356 
00357     ~TX_SOCKET()
00358         {
00359         if (_sock) _sock -> Delete();
00360         if (_client_sock_for_serv) _client_sock_for_serv -> Delete();
00361         }
00362 
00363         friend int txSendTo   (TX_SOCKET& to, const void* buf, int size_buf);
00364         friend int txRecvFrom (TX_SOCKET& to, void* buf, int size_buf);
00365         friend int txnAssert  (TX_SOCKET& asr);
00366         friend int txChangeSockType   (TX_SOCKET& to, sock_type blocking);
00367         friend SOCKET* txGetWinSocket (TX_SOCKET& what, bool main = true);
00369     };
00370 
00371 //}
00372 
00373 // prototypes
00374 //{
00397     TX_SOCKET txCreateSocket (sock_type type, const char* IP = NULL, int port = TX_STD_PORT,
00398                               sock_type blocking = TX_BLOCK, bool useTCP = true, const unsigned OueueSize = 0x10);
00399 
00436 
00437     int txSendTo (TX_SOCKET& to, const void* buf, int size_buf);
00438 
00479 
00480     int txRecvFrom (TX_SOCKET& to, void* buf, int size_buf);
00481 
00490 
00491     int txnAssert (TX_SOCKET& asr);
00492 
00502 
00503     int txChangeSockType (TX_SOCKET& to, sock_type blocking);
00504 
00514 
00515     SOCKET* txGetWinSocket (TX_SOCKET& what, bool main/* = true*/);
00516 
00517 //}
00518 
00519 // definitions (##--INTERANL--##)
00520 //{
00522 
00523 // txSmartSocket_
00524 //{
00525 
00526 SOCKET& txSmartSocket_ :: operator*()
00527 {
00528 return sock;
00529 }
00530 
00531 txSmartSocket_* txSmartSocket_ :: Create()
00532 {
00533 num_of_ref++;
00534 
00535 return this;
00536 }
00537 
00538 txSmartSocket_* txSmartSocket_ :: Delete()
00539 {
00540 if (num_of_ref == 0 && sock != INVALID_SOCKET)
00541     delete this;
00542 else
00543     num_of_ref--;
00544 
00545 return this;
00546 }
00547 
00548 //}
00549 
00550 // TX_SOCKET
00551 //{
00552 
00553 bool TX_SOCKET :: _txInitAsServer (const char*, u_short port, sock_type blocking, bool useTCP, const unsigned OueueSize)
00554     {
00555     addrinfo hints    = {};
00556     hints.ai_family   = AF_INET;
00557     hints.ai_socktype = (useTCP? SOCK_STREAM : SOCK_DGRAM);
00558     hints.ai_flags    = AI_PASSIVE;
00559 
00560     addrinfo *servinfo = NULL;
00561 
00562     int _port_ = port;
00563 
00564     char str[6] = "";
00565 
00566     sprintf (str, "%d", _port_);
00567 
00568     int err = getaddrinfo (NULL, str, &hints, &servinfo);
00569     if (err == -1) return false;
00570 
00571     _sock = NULL;
00572     for (addrinfo* p = servinfo; p; p = p->ai_next)
00573         {
00574         _sock = new txSmartSocket_ (socket (p->ai_family, p->ai_socktype, p->ai_protocol));
00575 
00576         if (_sock == NULL)
00577             {
00578             return false;
00579             }
00580 
00581         if ( (int) **_sock == -1)
00582             {
00583             delete _sock;
00584             continue;
00585             }
00586 
00587         if (bind (**_sock, p->ai_addr, int (p->ai_addrlen)) == -1)
00588             {
00589             delete _sock;
00590             continue;
00591             }
00592 
00593         break;
00594         }
00595 
00596     if (_sock == NULL)
00597         {
00598         return false;
00599         }
00600 
00601     if (!**_sock)
00602         {
00603         delete _sock;
00604         return false;
00605         }
00606 
00607     freeaddrinfo (servinfo);
00608 
00609     if (useTCP)
00610         {
00611         if (listen (**_sock, OueueSize)) return false;
00612 
00613         int client_addr_size = sizeof (_client_addr);
00614 
00615         _client_sock_for_serv = new txSmartSocket_(accept (**_sock, (sockaddr* ) &_client_addr, &client_addr_size));
00616 
00617         if (_client_sock_for_serv == NULL)
00618 
00619         if (**_client_sock_for_serv == 0)
00620             {
00621             delete _client_sock_for_serv;
00622             return false;
00623             }
00624         }
00625 
00626     if (blocking == TX_NONBLOCK)
00627         {
00628         u_long nonblocking = 1;
00629         if (ioctlsocket (**_client_sock_for_serv, FIONBIO, &nonblocking) == SOCKET_ERROR)
00630             {
00631             delete _client_sock_for_serv;
00632             return false;
00633             }
00634         }
00635 
00636     return true;
00637     }
00638 
00639 bool TX_SOCKET :: _txInitAsClient (const char* IP, u_short port, sock_type blocking, bool useTCP, const unsigned)
00640     {
00641     hostent* he = gethostbyname (IP);
00642 
00643     _sock = new txSmartSocket_ (useTCP? socket (AF_INET, SOCK_STREAM, IPPROTO_IP) :
00644                                         socket (AF_INET, SOCK_DGRAM, _broadcats? 0 : IPPROTO_UDP));
00645     if (_sock == NULL)
00646         return false;
00647 
00648     if (**_sock == INVALID_SOCKET)
00649         {
00650         delete _sock;
00651 
00652         return false;
00653         }
00654 
00655     char broadcast = _broadcats;
00656     if (_broadcats) if (setsockopt (**_sock, SOL_SOCKET, SO_BROADCAST, &broadcast, sizeof (broadcast)) == -1)
00657         return false;
00658 
00659     _sock_addr = {};
00660 
00661     _sock_addr.sin_family = AF_INET;
00662     _sock_addr.sin_port   = htons (port);
00663     _sock_addr.sin_addr   = * (in_addr*) he->h_addr;
00664 
00665     if (useTCP)
00666         if (connect (**_sock, (sockaddr* ) &_sock_addr, sizeof (_sock_addr)) != 0)
00667         {
00668         delete _sock;
00669         return false;
00670         }
00671 
00672     if (blocking == TX_NONBLOCK)
00673         {
00674         u_long nonblocking = 1;
00675         if (ioctlsocket (**_sock, FIONBIO, &nonblocking) == SOCKET_ERROR)
00676             {
00677             delete _sock;
00678             return false;
00679             }
00680         }
00681 
00682     return true;
00683     }
00684 
00685 //}
00686 
00687 int txSendTo (TX_SOCKET& to, const void* buf, int size_buf)
00688     {
00689     int answ = 0;
00690 
00691     if (to._broadcats)
00692         {
00693         answ = sendto (**(to._sock), (const char*) buf, size_buf, 0, (sockaddr *) &to._sock_addr, sizeof (to._sock_addr));
00694         return answ;
00695         }
00696 
00697     else if (to._TCP)
00698         {
00699         switch (to._type)
00700             {
00701             case TX_SERVER:   answ = send (**(to._client_sock_for_serv), (const char*) buf, size_buf, 0); break;
00702             case TX_CLIENT:   answ = send (**(to._sock),                 (const char*) buf, size_buf, 0); break;
00703 
00704             case TX_BLOCK:
00705             case TX_NONBLOCK: return TXN_ERROR;
00706 
00707             case TX_NOTYPE:   return 0;
00708 
00709             default:          return 0;
00710             }
00711         }
00712 
00713     else
00714         answ = sendto (**(to._sock), (const char*) buf, size_buf, 0, (sockaddr*) &to._sock_addr, sizeof (to._sock_addr));
00715 
00716     return answ;
00717     }
00718 
00719 int txRecvFrom (TX_SOCKET& to, void* buf, int size_buf)
00720     {
00721     int answ = 0;
00722 
00723     if (to._broadcats)
00724         {
00725         int SIZE_OF_STRUCTURE_FOR_XXX_WINDOWS = sizeof (to._sock_addr);
00726         answ = recvfrom (**(to._sock), (char*) buf, size_buf, 0, (sockaddr*) &to._sock_addr, &SIZE_OF_STRUCTURE_FOR_XXX_WINDOWS);
00727         }
00728 
00729     else if (to._TCP)
00730         {
00731         switch (to._type)
00732             {
00733             case TX_SERVER:   answ = recv (**(to._client_sock_for_serv), (char*) buf, size_buf, 0); break;
00734             case TX_CLIENT:   answ = recv (**(to._sock),                 (char*) buf, size_buf, 0); break;
00735 
00736             case TX_BLOCK:
00737             case TX_NONBLOCK: return TXN_ERROR;
00738 
00739             case TX_NOTYPE:   return 0;
00740 
00741             default:          return 0;
00742             }
00743         }
00744     else
00745         {
00746         int SIZE_OF_STRUCTURE_FOR_XXX_WINDOWS = sizeof (to._sock_addr);
00747         answ = recvfrom (**(to._sock), (char*) buf, size_buf, 0, (sockaddr*) &to._sock_addr, &SIZE_OF_STRUCTURE_FOR_XXX_WINDOWS);
00748         }
00749 
00750     return answ;
00751     }
00752 
00753 TX_SOCKET txCreateSocket (sock_type type, const char* IP/* = NULL*/,
00754                           int port /* = TX_STD_PORT*/, sock_type blocking /* = TX_BLOCK*/, bool useTCP /* = true*/, const unsigned OueueSize/* = 0x10*/)
00755     {
00756     return TX_SOCKET (type, IP, port, blocking, useTCP, OueueSize);
00757     }
00758 
00759 int txnAssert (TX_SOCKET& asr)
00760     {
00761     return (asr._init)? TXN_OK : TXN_NOT_CREATED;
00762     }
00763 
00764 int txChangeSockType (TX_SOCKET& to, sock_type blocking)
00765     {
00766     u_long mode = 0;
00767 
00768     switch (blocking)
00769         {
00770         case TX_BLOCK:    mode = 0; break;
00771         case TX_NONBLOCK: mode = 1; break;
00772 
00773         default:          return false;
00774         };
00775 
00776     if (ioctlsocket (*txGetWinSocket (to), FIONBIO, &mode) == SOCKET_ERROR) return false;
00777 
00778     to._type_ = blocking;
00779 
00780     return true;
00781     }
00782 
00783 SOCKET* txGetWinSocket (TX_SOCKET& what, bool main/* = true*/)
00784     {
00785     SOCKET* ret = NULL;
00786 
00787     switch (what._type)
00788         {
00789         case TX_CLIENT: ret = &**(what._sock);                                          break;
00790         case TX_SERVER: ret = main? &**(what._sock) : &**(what._client_sock_for_serv);  break;
00791 
00792         default:        ret = &**(what._sock);                                          break;
00793         }
00794 
00795     return ret;
00796     }
00797 
00799 //}
00800 
00801 // Dark side (Yes, we have cookies) (##--INTERANL--##)
00802 //{
00804 
00805 int  _txInitTX_NETWORK();
00806 void _txDestTX_NETWORK();
00807 
00808 WSADATA main_wsa_data = {};
00809 int int_for_init = _txInitTX_NETWORK();
00810 
00811 int _txInitTX_NETWORK()
00812     {
00813     WSAStartup (0x0202, &main_wsa_data);
00814     atexit (_txDestTX_NETWORK);
00815 
00816     return 0;
00817     }
00818 
00819 void _txDestTX_NETWORK()
00820     {
00821     WSACleanup();
00822     }
00823 
00824 #if !defined (__MODULE)
00825 
00826     #define __MODULE "TXNetwork appilication using small TXLib.\n"                   // Ты это не видел. Забудь :)
00827 
00828 #endif
00829 
00830 #if defined (__MODULE) || defined (__VERSION) || defined (__DESCRIPTION) || defined (__AUTHOR)
00831 
00832     #ifndef __MODULE
00833     #define __MODULE       "TXNetwork appilication using small TXLib." "\n" \
00834                            "#define __MODULE to set the name.\n"
00835     #endif
00836 
00837     #ifndef __VERSION
00838     #define __VERSION      "sqrt (-1)" "\n" \
00839                            "#define __VERSION to set the string value.\n"
00840     #endif
00841 
00842     #ifndef __DESCRIPTION
00843     #define __DESCRIPTION  "Маленькое мышиное приложение, использующее великий TXNetwork и маленький TXLib" "\n" \
00844                            "#define __DESCRIPTION to override project role.\n"
00845     #endif
00846 
00847     #ifndef __AUTHOR
00848     #define __AUTHOR       "_RedMan_, 2015" "\n" \
00849                            "#define __AUTHOR to override this name."
00850     #endif
00851 
00852 #endif
00853 
00854 // OMG!!! You found this!!! +------\
00855 //                          +-----||
00856 //                                ||
00857 //                                ||
00858 //                                \/
00859 //             .-----------------------------.
00860 //            /  _   _   _      *  __  __   /|
00861 //           /  / \ / \ / \ |_/ | |_  (_   / |
00862 //          /   \_  \_/ \_/ | \ | |__ ,_/ /  |
00863 //         :.____________________________/   /
00864 //         |  .--.   .--.   .--.   .--.  |  /
00865 //         | (    ) (    ) (    ) (    ) | /
00866 //         |  '--'   '--'   '--'   '--'  |/
00867 //         '-----------------------------'
00868 //
00869 
00871 
00872 //}
00873 
00874 #pragma GCC diagnostic pop
00875 
00876 #endif