SocketHandle.h 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. /************************************************************************/
  2. /* Copyright (C), 2016-2020, [IT], 保留所有权利;
  3. /* 模 块 名:SocketHandle;
  4. /* 描 述:Socket Communication Classes;
  5. /*
  6. /* 版 本:[V 1.4] IPv6 support;
  7. /* 版 本:[V 1.3] Update for Asynchronous mode / Linux port;
  8. /* 版 本:[V 1.2] Update interface for TCP remote connection;
  9. /* 版 本:[V 1.1] Added multicast support;
  10. /* 作 者:[IT];
  11. /* 日 期:[2/23/2016];
  12. /*
  13. /*
  14. /* 注 意:;
  15. /*
  16. /* 修改记录:[IT];
  17. /* 修改日期:;
  18. /* 修改版本:;
  19. /* 修改内容:;
  20. /************************************************************************/
  21. #ifndef __SOCKETHANDLE_20160228__
  22. #define __SOCKETHANDLE_20160228__
  23. #pragma once
  24. #ifdef WIN32
  25. #include <winsock2.h>
  26. #include <ws2tcpip.h>
  27. #elif BSD_SOCKET
  28. #include "platform.h"
  29. #endif
  30. /************************************************************************/
  31. /* Copyright (C), 2016-2020, [IT], 保留所有权利;
  32. /* 模 块 名:SockAddrIn;
  33. /* 描 述:SockAddrIn结构体,内部封装了 SOCKADDR_STORAGE (IPv4: SOCKADDR_IN, IPv6: SOCKADDR_IN6) 结构体;
  34. /*
  35. /* // IPV4地址结构;
  36. /* struct SOCKADDR_IN{
  37. /* SHORT sin_family; // 地址簇;
  38. /* USHORT sin_port; // 端口号;
  39. /* in_addr sin_addr; // 地址;
  40. /* CHAR sin_zero[8]; // IPV4为了填充结构体来保持固定大小,无意义;
  41. /* };
  42. /*
  43. /* struct IN_ADDR{
  44. /* unsigned long s_addr; // 地址;
  45. /* };
  46. /*
  47. /* // IPV6地址结构;
  48. /* struct SOCKADDR_IN6{
  49. /* USHORT sin6_family; // 地址簇类型:AF_INET6;
  50. /* USHORT sin6_port; // 16位端口号;
  51. /* ULONG sin6_flowinfo; // 32位流标签;
  52. /* in6_addr sin6_addr; // 128位IP地址;
  53. /* union
  54. /* {
  55. /* ULONG sin6_scope_id; // Set of interfaces for a scope.
  56. /* SCOPE_ID sin6_scope_struct;
  57. /* };
  58. /* };
  59. /*
  60. /* struct in6_addr {
  61. /* union {
  62. /* UCHAR Byte[16];
  63. /* USHORT Word[8];
  64. /* } u;
  65. /* } ;
  66. /*
  67. /* typedef struct {
  68. /* union {
  69. /* struct
  70. /* {
  71. /* ULONG Zone : 28;
  72. /* ULONG Level : 4;
  73. /* };
  74. /* ULONG Value;
  75. /* };
  76. /* } SCOPE_ID, *PSCOPE_ID;
  77. /*
  78. /* 版 本:[V];
  79. /* 作 者:[IT];
  80. /* 日 期:[2/23/2016];
  81. /*
  82. /*
  83. /* 注 意:;
  84. /*
  85. /* 修改记录:[IT];
  86. /* 修改日期:;
  87. /* 修改版本:;
  88. /* 修改内容:;
  89. /************************************************************************/
  90. struct SockAddrIn : public sockaddr_storage
  91. {
  92. public:
  93. SockAddrIn();
  94. ~SockAddrIn();
  95. // 拷贝构造;
  96. SockAddrIn(IN const SockAddrIn& sin);
  97. // 复制函数;
  98. SockAddrIn& Copy(IN const SockAddrIn& sin);
  99. // 清空结构体;
  100. void Clear();
  101. // 对比地址是否相同;
  102. bool IsEqual(IN const SockAddrIn& sin) const;
  103. // 如果NULLAddr无效,返回TRUE;
  104. bool IsNull() const { return IsEqual(NULLAddr); }
  105. // 返回地址簇类型;
  106. short GetFamily() const { return ss_family; }
  107. // 返回IPV4网络地址;
  108. ULONG GetIPAddr() const { return ((SOCKADDR_IN*)this)->sin_addr.s_addr; }
  109. // 获取网络端口;
  110. short GetPort() const { return ((SOCKADDR_IN*)this)->sin_port; }
  111. // 创建服务端地址(同时支持IPV4和IPV6);
  112. bool CreateFrom(IN LPCTSTR pszAddr, IN LPCTSTR pszService, IN int nFamily = AF_INET);
  113. // 创建服务端地址(只支持IPV4);
  114. bool CreateFrom(IN ULONG lIPAddr, IN USHORT nPort, IN int nFamily = AF_INET, IN bool bFmtHost = true);
  115. // 赋值拷贝函数,返回this指针引用;
  116. SockAddrIn& operator=(const SockAddrIn& sin) { return Copy( sin ); }
  117. // 相等操作判断,相等返回TRUE;
  118. bool operator==(const SockAddrIn& sin) const { return IsEqual( sin ); }
  119. // 不等操作判断,如果不同返回TRUE;
  120. bool operator!=(const SockAddrIn& sin) const { return !IsEqual( sin ); }
  121. // 转换SOCKADDR地址,返回SOCKADDR格式的this对象;
  122. operator LPSOCKADDR() { return reinterpret_cast<LPSOCKADDR>(this); }
  123. // 转换PIN6_ADDR地址,返回PIN6_ADDR格式的this对象;
  124. operator const IN6_ADDR*() const { return reinterpret_cast<const IN6_ADDR*>(this); }
  125. // 转换PIN6_ADDR地址,返回PIN6_ADDR格式的this对象;
  126. operator PIN6_ADDR() { return reinterpret_cast<PIN6_ADDR>(this); }
  127. // 返回结构体(SOCKADDR_IN) 或 (SOCKADDR_STORAGE)的大小(由地址协议簇决定);
  128. size_t Size() const { return (ss_family == AF_INET) ? sizeof(sockaddr_in) : sizeof(sockaddr_storage); }
  129. // 以SOCKADDR_IN结构体来初始化this对象;
  130. void SetAddr(const sockaddr_in* psin) { SetAddr(reinterpret_cast<const sockaddr_storage*>(psin)); }
  131. // 以SOCKADDR_IN6结构体来初始化this对象;
  132. void SetAddr(const sockaddr_in6* psin) { SetAddr(reinterpret_cast<const sockaddr_storage*>(psin)); }
  133. // 以SOCKADDR_STROAGE结构体来初始化this对象;
  134. void SetAddr(const sockaddr_storage* pss) { ss_family = pss->ss_family; memcpy(this, pss, Size()); }
  135. static SockAddrIn NULLAddr; // 空地址;
  136. };
  137. #ifdef WIN32
  138. typedef LPWSAOVERLAPPED_COMPLETION_ROUTINE LPWSACOMPLETIONROUTINE;
  139. #endif
  140. // Jeff.add.2014.08.07--------------------------------------------------------
  141. #define SOCKET_SERVER_PORT 6432
  142. // Jeff.注意, 这里单个包的大小不能超过该设置数值,一般设置为10*1024即10KB; 不过实际中可根据实际情况处理,如使用TCP来传输数据的话;
  143. #define SOCKET_BUFFSIZE 1024*64
  144. // Jeff.add.2014.08.07--------------------------------------------------------
  145. /************************************************************************/
  146. /* Copyright (C), 2016-2020, [IT], 保留所有权利;
  147. /* 模 块 名:CSocketHandle类;
  148. /* 描 述:套接字通信类;
  149. /*
  150. /* 版 本:[V];
  151. /* 作 者:[IT];
  152. /* 日 期:[2/29/2016];
  153. /*
  154. /*
  155. /* 注 意:;
  156. /*
  157. /* 修改记录:[IT];
  158. /* 修改日期:;
  159. /* 修改版本:;
  160. /* 修改内容:;
  161. /************************************************************************/
  162. class CSocketHandle
  163. {
  164. public:
  165. CSocketHandle();
  166. ~CSocketHandle();
  167. // 套接字是否打开,打开返回TRUE;
  168. bool IsOpen() const;
  169. // 返回套接字句柄(如果对象关闭,句柄值为INVALID_SOCKET);
  170. SOCKET GetSocket() const;
  171. // 获取套接字类型(返回-1表示不是一个有效的套接字)
  172. int GetSocketType() const;
  173. // 附加套接字;
  174. bool Attach(IN SOCKET sock);
  175. // 从类中分离套接字;
  176. SOCKET Detach();
  177. // 获取套接字名(本地地址);
  178. bool GetSockName(OUT SockAddrIn& saddr_in) const;
  179. // 获取点对点的套接接名(获取Peer地址);
  180. bool GetPeerName(OUT SockAddrIn& saddr_in) const;
  181. // 关闭套接字;
  182. void Close();
  183. // 记录多播地址;
  184. bool AddMembership(IN LPCTSTR pszIPAddr, IN LPCTSTR pszNIC);
  185. // 移除多播地址;
  186. bool DropMembership(IN LPCTSTR pszIPAddr, IN LPCTSTR pszNIC);
  187. // 创建服务端套接字;
  188. bool CreateSocket(IN LPCTSTR pszHostName, IN LPCTSTR pszServiceName, IN int nFamily, IN int nType, IN UINT uOptions = 0);
  189. // 客户端连接服务端;
  190. bool ConnectTo(IN LPCTSTR pszHostName, IN LPCTSTR pszRemote, IN LPCTSTR pszServiceName, IN int nFamily, IN int nType);
  191. // 从套接字读取内容;
  192. DWORD Read(OUT LPBYTE lpBuffer, IN DWORD dwSize, IN LPSOCKADDR lpAddrIn = NULL, IN DWORD dwTimeout = INFINITE);
  193. #ifdef WIN32
  194. // 异步从套接字读取内容;
  195. DWORD ReadEx(OUT LPBYTE lpBuffer, IN DWORD dwSize, IN LPSOCKADDR lpAddrIn, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSACOMPLETIONROUTINE lpCompletionRoutine);
  196. #endif
  197. // 向目标套接字发送内容;
  198. DWORD Write(IN const LPBYTE lpBuffer, IN DWORD dwCount, IN const LPSOCKADDR lpAddrIn = NULL, IN DWORD dwTimeout = INFINITE);
  199. #ifdef WIN32
  200. // 异步向目标套接字发送内容;
  201. DWORD WriteEx(IN const LPBYTE lpBuffer, IN DWORD dwCount, IN const LPSOCKADDR lpAddrIn, IN LPWSAOVERLAPPED lpOverlapped, IN LPWSACOMPLETIONROUTINE lpCompletionRoutine);
  202. #endif
  203. #ifdef WIN32
  204. // Control the mode of a socket (asynchronous mode);
  205. bool IOControl(
  206. IN DWORD dwIoCode,
  207. IN LPBYTE lpInBuffer,
  208. IN DWORD cbInBuffer,
  209. IN LPBYTE lpOutBuffer,
  210. IN DWORD cbOutBuffer,
  211. IN LPDWORD lpcbBytesReturned,
  212. IN LPWSAOVERLAPPED lpOverlapped,
  213. IN LPWSACOMPLETIONROUTINE lpCompletionRoutine
  214. );
  215. // Get Overlapped result (asynchronous mode);
  216. bool GetTransferOverlappedResult(IN LPWSAOVERLAPPED lpOverlapped, IN LPDWORD lpcbTransfer, IN bool bWait = true, IN LPDWORD lpdwFlags = 0);
  217. #endif
  218. // Initialize Winsock library. This function calls WSAStartup;
  219. static bool InitLibrary(IN WORD wVersion);
  220. // Release Winsock library;
  221. static bool ReleaseLibrary();
  222. // Wait for a new connection;
  223. static SOCKET WaitForConnection(IN SOCKET sock);
  224. // Shutdown a connection;
  225. static bool ShutdownConnection(IN SOCKET sock);
  226. // Check if IP address is unicast (network order);
  227. static bool IsUnicastIP( IN ULONG ulAddr );
  228. // Check if IP address is multicast (network order);
  229. static bool IsMulticastIP( IN ULONG ulAddr );
  230. // Format IP address to string;
  231. static bool FormatIP(LPTSTR pszIPAddr, UINT nSize, ULONG ulAddr, bool bFmtHost);
  232. // Format IP address to string;
  233. static bool FormatIP(LPTSTR pszIPAddr, UINT nSize, const SockAddrIn& addrIn);
  234. // Get service port number;
  235. static USHORT GetPortNumber( LPCTSTR pszServiceName );
  236. // Get IP address of a host;
  237. static ULONG GetIPAddress( LPCTSTR pszHostName );
  238. // Get current localname for this machine;
  239. static bool GetLocalName(LPTSTR pszName, UINT nSize);
  240. // Get current (default) IP address for this machine;
  241. static bool GetLocalAddress(LPTSTR pszAddress, UINT nSize, int nFamily = AF_INET);
  242. // Get IP address info of a host (Supports: IPv4 and IPv6);
  243. static bool GetAddressInfo( LPCTSTR pszHostName, LPCTSTR pszServiceName, int nFamily, SockAddrIn& sockAddr);
  244. // CSocketHandle - data
  245. protected:
  246. SOCKET m_hSocket; ///< socket handle
  247. // Jeff.add.2014.08.07-----------------------------------.
  248. public:
  249. unsigned char m_szpendingbuf[SOCKET_BUFFSIZE];
  250. unsigned int m_npendingSize;
  251. CRITICAL_SECTION m_hClient2SrvSection;
  252. // Jeff.add.2014.08.07-----------------------------------.
  253. };
  254. #endif // __SOCKETHANDLE_20160228__