![]() |
TX Library Help – Version: 00173a, Revision: 174
|
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