AsyncSocketEx.cpp 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862
  1. /*CAsyncSocketEx by Tim Kosse ([email protected])
  2. Version 1.3 (2003-04-26)
  3. --------------------------------------------------------
  4. Introduction:
  5. -------------
  6. CAsyncSocketEx is a replacement for the MFC class CAsyncSocket.
  7. This class was written because CAsyncSocket is not the fastest WinSock
  8. wrapper and it's very hard to add new functionality to CAsyncSocket
  9. derived classes. This class offers the same functionality as CAsyncSocket.
  10. Also, CAsyncSocketEx offers some enhancements which were not possible with
  11. CAsyncSocket without some tricks.
  12. How do I use it?
  13. ----------------
  14. Basically exactly like CAsyncSocket.
  15. To use CAsyncSocketEx, just replace all occurrences of CAsyncSocket in your
  16. code with CAsyncSocketEx, if you did not enhance CAsyncSocket yourself in
  17. any way, you won't have to change anything else in your code.
  18. Why is CAsyncSocketEx faster?
  19. -----------------------------
  20. CAsyncSocketEx is slightly faster when dispatching notification event messages.
  21. First have a look at the way CAsyncSocket works. For each thread that uses
  22. CAsyncSocket, a window is created. CAsyncSocket calls WSAAsyncSelect with
  23. the handle of that window. Until here, CAsyncSocketEx works the same way.
  24. But CAsyncSocket uses only one window message (WM_SOCKET_NOTIFY) for all
  25. sockets within one thread. When the window recieve WM_SOCKET_NOTIFY, wParam
  26. contains the socket handle and the window looks up an CAsyncSocket instance
  27. using a map. CAsyncSocketEx works differently. It's helper window uses a
  28. wide range of different window messages (WM_USER through 0xBFFF) and passes
  29. a different message to WSAAsyncSelect for each socket. When a message in
  30. the specified range is received, CAsyncSocketEx looks up the pointer to a
  31. CAsyncSocketEx instance in an Array using the index of message - WM_USER.
  32. As you can see, CAsyncSocketEx uses the helper window in a more efficient
  33. way, as it don't have to use the slow maps to lookup it's own instance.
  34. Still, speed increase is not very much, but it may be noticeable when using
  35. a lot of sockets at the same time.
  36. Please note that the changes do not affect the raw data throughput rate,
  37. CAsyncSocketEx only dispatches the notification messages faster.
  38. What else does CAsyncSocketEx offer?
  39. ------------------------------------
  40. CAsyncSocketEx offers a flexible layer system. One example is the proxy layer.
  41. Just create an instance of the proxy layer, configure it and add it to the layer
  42. chain of your CAsyncSocketEx instance. After that, you can connect through
  43. proxies.
  44. Benefit: You don't have to change much to use the layer system.
  45. Another layer that is currently in development is the SSL layer to establish
  46. SSL encrypted connections.
  47. License
  48. -------
  49. Feel free to use this class, as long as you don't claim that you wrote it
  50. and this copyright notice stays intact in the source files.
  51. If you use this class in commercial applications, please send a short message
  52. to [email protected]
  53. */
  54. #include "stdafx.h"
  55. #include "AsyncSocketEx.h"
  56. #include "wtypes.h"
  57. #include "oleauto.h"
  58. #include "atlconv.h"
  59. #ifndef NOLAYERS
  60. #include "AsyncSocketExLayer.h"
  61. #endif //NOLAYERS
  62. #ifdef MPEXT
  63. #pragma warn -inl
  64. #endif
  65. #ifdef _DEBUG
  66. #undef THIS_FILE
  67. static char THIS_FILE[]=__FILE__;
  68. #endif
  69. #ifndef CCRITICALSECTIONWRAPPERINCLUDED
  70. class CCriticalSectionWrapper
  71. {
  72. public:
  73. CCriticalSectionWrapper()
  74. {
  75. m_bInitialized = TRUE;
  76. InitializeCriticalSection(&m_criticalSection);
  77. }
  78. ~CCriticalSectionWrapper()
  79. {
  80. if (m_bInitialized)
  81. DeleteCriticalSection(&m_criticalSection);
  82. m_bInitialized = FALSE;
  83. }
  84. void Lock()
  85. {
  86. if (m_bInitialized)
  87. EnterCriticalSection(&m_criticalSection);
  88. }
  89. void Unlock()
  90. {
  91. if (m_bInitialized)
  92. LeaveCriticalSection(&m_criticalSection);
  93. }
  94. protected:
  95. CRITICAL_SECTION m_criticalSection;
  96. BOOL m_bInitialized;
  97. };
  98. #define CCRITICALSECTIONWRAPPERINCLUDED
  99. #endif
  100. CCriticalSectionWrapper CAsyncSocketEx::m_sGlobalCriticalSection;
  101. CAsyncSocketEx::t_AsyncSocketExThreadDataList *CAsyncSocketEx::m_spAsyncSocketExThreadDataList = 0;
  102. #ifndef _AFX
  103. #ifndef VERIFY
  104. #define VERIFY(x) (void(x))
  105. #endif //VERIFY
  106. #ifndef ASSERT
  107. #define ASSERT(x)
  108. #endif //ASSERT
  109. #endif //_AFX
  110. /////////////////////////////
  111. //Helper Window class
  112. #define WM_SOCKETEX_NOTIFY (WM_USER+3)
  113. #define MAX_SOCKETS (0xBFFF-WM_SOCKETEX_NOTIFY+1)
  114. class CAsyncSocketExHelperWindow
  115. {
  116. public:
  117. CAsyncSocketExHelperWindow(CAsyncSocketEx::t_AsyncSocketExThreadData* pThreadData)
  118. {
  119. //Initialize data
  120. m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
  121. memset(m_pAsyncSocketExWindowData, 0, 512*sizeof(t_AsyncSocketExWindowData));
  122. m_nWindowDataSize=512;
  123. m_nSocketCount=0;
  124. m_nWindowDataPos=0;
  125. m_pThreadData = pThreadData;
  126. //Create window
  127. WNDCLASSEX wndclass;
  128. wndclass.cbSize=sizeof wndclass;
  129. wndclass.style=0;
  130. wndclass.lpfnWndProc=WindowProc;
  131. wndclass.cbClsExtra=0;
  132. wndclass.cbWndExtra=0;
  133. wndclass.hInstance=GetModuleHandle(0);
  134. wndclass.hIcon=0;
  135. wndclass.hCursor=0;
  136. wndclass.hbrBackground=0;
  137. wndclass.lpszMenuName=0;
  138. wndclass.lpszClassName=_T("CAsyncSocketEx Helper Window");
  139. wndclass.hIconSm=0;
  140. RegisterClassEx(&wndclass);
  141. m_hWnd=CreateWindow(_T("CAsyncSocketEx Helper Window"), _T("CAsyncSocketEx Helper Window"), 0, 0, 0, 0, 0, 0, 0, 0, GetModuleHandle(0));
  142. ASSERT(m_hWnd);
  143. SetWindowLongPtr(m_hWnd, GWL_USERDATA, (LONG)this);
  144. };
  145. virtual ~CAsyncSocketExHelperWindow()
  146. {
  147. //Clean up socket storage
  148. delete [] m_pAsyncSocketExWindowData;
  149. m_pAsyncSocketExWindowData=0;
  150. m_nWindowDataSize=0;
  151. m_nSocketCount=0;
  152. //Destroy window
  153. if (m_hWnd)
  154. {
  155. DestroyWindow(m_hWnd);
  156. m_hWnd=0;
  157. }
  158. }
  159. //Adds a socket to the list of attached sockets
  160. BOOL AddSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
  161. {
  162. ASSERT(pSocket);
  163. if (!m_nWindowDataSize)
  164. {
  165. ASSERT(!m_nSocketCount);
  166. m_nWindowDataSize=512;
  167. m_pAsyncSocketExWindowData=new t_AsyncSocketExWindowData[512]; //Reserve space for 512 active sockets
  168. memset(m_pAsyncSocketExWindowData, 0, 512*sizeof(t_AsyncSocketExWindowData));
  169. }
  170. if (nSocketIndex!=-1)
  171. {
  172. ASSERT(m_pAsyncSocketExWindowData);
  173. ASSERT(m_nWindowDataSize>nSocketIndex);
  174. ASSERT(m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket==pSocket);
  175. ASSERT(m_nSocketCount);
  176. return TRUE;
  177. }
  178. //Increase socket storage if too small
  179. if (m_nSocketCount>=(m_nWindowDataSize-10))
  180. {
  181. int nOldWindowDataSize=m_nWindowDataSize;
  182. ASSERT(m_nWindowDataSize<MAX_SOCKETS);
  183. m_nWindowDataSize+=512;
  184. if (m_nWindowDataSize>MAX_SOCKETS)
  185. m_nWindowDataSize=MAX_SOCKETS;
  186. t_AsyncSocketExWindowData *tmp=m_pAsyncSocketExWindowData;
  187. m_pAsyncSocketExWindowData = new t_AsyncSocketExWindowData[m_nWindowDataSize];
  188. memcpy(m_pAsyncSocketExWindowData, tmp, nOldWindowDataSize * sizeof(t_AsyncSocketExWindowData));
  189. memset(m_pAsyncSocketExWindowData+nOldWindowDataSize, 0, (m_nWindowDataSize-nOldWindowDataSize)*sizeof(t_AsyncSocketExWindowData));
  190. delete [] tmp;
  191. }
  192. //Search for free slot
  193. for (int i=m_nWindowDataPos;i<(m_nWindowDataSize+m_nWindowDataPos);i++)
  194. {
  195. if (!m_pAsyncSocketExWindowData[i%m_nWindowDataSize].m_pSocket)
  196. {
  197. m_pAsyncSocketExWindowData[i%m_nWindowDataSize].m_pSocket=pSocket;
  198. nSocketIndex=i%m_nWindowDataSize;
  199. m_nWindowDataPos=(i+1)%m_nWindowDataSize;
  200. m_nSocketCount++;
  201. return TRUE;
  202. }
  203. }
  204. //No slot found, maybe there are too much sockets!
  205. return FALSE;
  206. }
  207. //Removes a socket from the socket storage
  208. BOOL RemoveSocket(CAsyncSocketEx *pSocket, int &nSocketIndex)
  209. {
  210. ASSERT(pSocket);
  211. if (nSocketIndex==-1)
  212. return TRUE;
  213. // Remove additional messages from queue
  214. MSG msg;
  215. while (PeekMessage(&msg, m_hWnd, WM_SOCKETEX_NOTIFY + nSocketIndex, WM_SOCKETEX_NOTIFY + nSocketIndex, PM_REMOVE));
  216. ASSERT(m_pAsyncSocketExWindowData);
  217. ASSERT(m_nWindowDataSize>0);
  218. ASSERT(m_nSocketCount>0);
  219. ASSERT(m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket==pSocket);
  220. m_pAsyncSocketExWindowData[nSocketIndex].m_pSocket=0;
  221. nSocketIndex=-1;
  222. m_nSocketCount--;
  223. return TRUE;
  224. }
  225. void RemoveLayers(CAsyncSocketEx *pOrigSocket)
  226. {
  227. // Remove all layer messages from old socket
  228. std::list<MSG> msgList;
  229. MSG msg;
  230. while (PeekMessage(&msg, m_hWnd, WM_USER, WM_USER, PM_REMOVE))
  231. {
  232. //Verify parameters, lookup socket and notification message
  233. //Verify parameters
  234. if (msg.wParam >= static_cast<UINT>(m_nWindowDataSize)) //Index is within socket storage
  235. continue;
  236. CAsyncSocketEx *pSocket = m_pAsyncSocketExWindowData[msg.wParam].m_pSocket;
  237. CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg=(CAsyncSocketExLayer::t_LayerNotifyMsg *)msg.lParam;
  238. if (!pMsg || !pSocket || pSocket == pOrigSocket || pSocket->m_SocketData.hSocket != pMsg->hSocket)
  239. {
  240. delete pMsg;
  241. continue;
  242. }
  243. msgList.push_back(msg);
  244. }
  245. for (std::list<MSG>::iterator iter = msgList.begin(); iter != msgList.end(); iter++)
  246. PostMessage(m_hWnd, iter->message, iter->wParam, iter->lParam);
  247. }
  248. //Processes event notifications sent by the sockets or the layers
  249. static LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
  250. {
  251. //Verify parameters
  252. ASSERT(hWnd);
  253. if (!hWnd)
  254. return 0;
  255. CAsyncSocketExHelperWindow *pWnd=(CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWL_USERDATA);
  256. if (message>=WM_SOCKETEX_NOTIFY)
  257. {
  258. ASSERT(pWnd);
  259. if (message<static_cast<UINT>(WM_SOCKETEX_NOTIFY+pWnd->m_nWindowDataSize)) //Index is within socket storage
  260. {
  261. //Lookup socket and verify if it's valid
  262. CAsyncSocketEx *pSocket=pWnd->m_pAsyncSocketExWindowData[message-WM_SOCKETEX_NOTIFY].m_pSocket;
  263. SOCKET hSocket=wParam;
  264. if (!pSocket)
  265. return 0;
  266. if (hSocket==INVALID_SOCKET)
  267. return 0;
  268. if (pSocket->m_SocketData.hSocket != hSocket)
  269. return 0;
  270. int nEvent=lParam&0xFFFF;
  271. int nErrorCode=lParam>>16;
  272. //Dispatch notification
  273. #ifndef NOLAYERS
  274. if (!pSocket->m_pFirstLayer)
  275. {
  276. #endif //NOLAYERS
  277. //Dispatch to CAsyncSocketEx instance
  278. switch (nEvent)
  279. {
  280. case FD_READ:
  281. #ifndef NOSOCKETSTATES
  282. if (pSocket->GetState() == connecting && !nErrorCode)
  283. {
  284. pSocket->m_nPendingEvents |= FD_READ;
  285. break;
  286. }
  287. else if (pSocket->GetState() == attached)
  288. pSocket->SetState(connected);
  289. if (pSocket->GetState() != connected)
  290. break;
  291. // Ignore further FD_READ events after FD_CLOSE has been received
  292. if (pSocket->m_SocketData.onCloseCalled)
  293. break;
  294. #endif //NOSOCKETSTATES
  295. if (pSocket->m_lEvent & FD_READ)
  296. {
  297. DWORD nBytes = 0;
  298. if (!nErrorCode)
  299. if (!pSocket->IOCtl(FIONREAD, &nBytes))
  300. nErrorCode = WSAGetLastError();
  301. #ifndef NOSOCKETSTATES
  302. if (nErrorCode)
  303. pSocket->SetState(aborted);
  304. #endif //NOSOCKETSTATES
  305. if (nBytes != 0 || nErrorCode != 0)
  306. pSocket->OnReceive(nErrorCode);
  307. }
  308. break;
  309. case FD_FORCEREAD: //Forceread does not check if there's data waiting
  310. #ifndef NOSOCKETSTATES
  311. if (pSocket->GetState() == connecting && !nErrorCode)
  312. {
  313. pSocket->m_nPendingEvents |= FD_FORCEREAD;
  314. break;
  315. }
  316. else if (pSocket->GetState() == attached)
  317. pSocket->SetState(connected);
  318. if (pSocket->GetState() != connected)
  319. break;
  320. #endif //NOSOCKETSTATES
  321. if (pSocket->m_lEvent & FD_READ)
  322. {
  323. #ifndef NOSOCKETSTATES
  324. if (nErrorCode)
  325. pSocket->SetState(aborted);
  326. #endif //NOSOCKETSTATES
  327. pSocket->OnReceive(nErrorCode);
  328. }
  329. break;
  330. case FD_WRITE:
  331. #ifndef NOSOCKETSTATES
  332. if (pSocket->GetState() == connecting && !nErrorCode)
  333. {
  334. pSocket->m_nPendingEvents |= FD_WRITE;
  335. break;
  336. }
  337. else if (pSocket->GetState() == attached && !nErrorCode)
  338. pSocket->SetState(connected);
  339. if (pSocket->GetState() != connected)
  340. break;
  341. #endif //NOSOCKETSTATES
  342. if (pSocket->m_lEvent & FD_WRITE)
  343. {
  344. #ifndef NOSOCKETSTATES
  345. if (nErrorCode)
  346. pSocket->SetState(aborted);
  347. #endif //NOSOCKETSTATES
  348. pSocket->OnSend(nErrorCode);
  349. }
  350. break;
  351. case FD_CONNECT:
  352. #ifndef NOSOCKETSTATES
  353. if (pSocket->GetState() == connecting)
  354. {
  355. if (nErrorCode && pSocket->m_SocketData.nextAddr)
  356. {
  357. if (pSocket->TryNextProtocol())
  358. break;
  359. }
  360. pSocket->SetState(connected);
  361. }
  362. else if (pSocket->GetState() == attached && !nErrorCode)
  363. pSocket->SetState(connected);
  364. #endif //NOSOCKETSTATES
  365. if (pSocket->m_lEvent & FD_CONNECT)
  366. pSocket->OnConnect(nErrorCode);
  367. #ifndef NOSOCKETSTATES
  368. if (!nErrorCode)
  369. {
  370. if ((pSocket->m_nPendingEvents&FD_READ) && pSocket->GetState() == connected)
  371. pSocket->OnReceive(0);
  372. if ((pSocket->m_nPendingEvents&FD_FORCEREAD) && pSocket->GetState() == connected)
  373. pSocket->OnReceive(0);
  374. if ((pSocket->m_nPendingEvents&FD_WRITE) && pSocket->GetState() == connected)
  375. pSocket->OnSend(0);
  376. }
  377. pSocket->m_nPendingEvents = 0;
  378. #endif
  379. break;
  380. case FD_ACCEPT:
  381. #ifndef NOSOCKETSTATES
  382. if (pSocket->GetState() != listening && pSocket->GetState() != attached)
  383. break;
  384. #endif //NOSOCKETSTATES
  385. if (pSocket->m_lEvent & FD_ACCEPT)
  386. pSocket->OnAccept(nErrorCode);
  387. break;
  388. case FD_CLOSE:
  389. #ifndef NOSOCKETSTATES
  390. if (pSocket->GetState() != connected && pSocket->GetState() != attached)
  391. break;
  392. // If there are still bytes left to read, call OnReceive instead of
  393. // OnClose and trigger a new OnClose
  394. DWORD nBytes = 0;
  395. if (!nErrorCode && pSocket->IOCtl(FIONREAD, &nBytes))
  396. {
  397. if (nBytes > 0)
  398. {
  399. // Just repeat message.
  400. PostMessage(hWnd, message, wParam, lParam);
  401. pSocket->m_SocketData.onCloseCalled = true;
  402. pSocket->OnReceive(WSAESHUTDOWN);
  403. break;
  404. }
  405. }
  406. pSocket->SetState(nErrorCode?aborted:closed);
  407. #endif //NOSOCKETSTATES
  408. pSocket->OnClose(nErrorCode);
  409. break;
  410. }
  411. }
  412. #ifndef NOLAYERS
  413. else //Dispatch notification to the lowest layer
  414. {
  415. if (nEvent == FD_READ)
  416. {
  417. // Ignore further FD_READ events after FD_CLOSE has been received
  418. if (pSocket->m_SocketData.onCloseCalled)
  419. return 0;
  420. DWORD nBytes;
  421. if (!pSocket->IOCtl(FIONREAD, &nBytes))
  422. nErrorCode = WSAGetLastError();
  423. if (nBytes != 0 || nErrorCode != 0)
  424. pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
  425. }
  426. else if (nEvent == FD_CLOSE)
  427. {
  428. // If there are still bytes left to read, call OnReceive instead of
  429. // OnClose and trigger a new OnClose
  430. DWORD nBytes = 0;
  431. if (!nErrorCode && pSocket->IOCtl(FIONREAD, &nBytes))
  432. {
  433. if (nBytes > 0)
  434. {
  435. // Just repeat message.
  436. pSocket->ResendCloseNotify();
  437. pSocket->m_pLastLayer->CallEvent(FD_READ, 0);
  438. return 0;
  439. }
  440. }
  441. pSocket->m_SocketData.onCloseCalled = true;
  442. pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
  443. }
  444. else
  445. {
  446. pSocket->m_pLastLayer->CallEvent(nEvent, nErrorCode);
  447. }
  448. }
  449. }
  450. #endif //NOLAYERS
  451. return 0;
  452. }
  453. #ifndef NOLAYERS
  454. else if (message == WM_USER) //Notification event sent by a layer
  455. {
  456. ASSERT(pWnd);
  457. if (wParam >= static_cast<UINT>(pWnd->m_nWindowDataSize)) //Index is within socket storage
  458. {
  459. return 0;
  460. }
  461. CAsyncSocketEx *pSocket=pWnd->m_pAsyncSocketExWindowData[wParam].m_pSocket;
  462. CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg=(CAsyncSocketExLayer::t_LayerNotifyMsg *)lParam;
  463. if (!pMsg || !pSocket || pSocket->m_SocketData.hSocket != pMsg->hSocket)
  464. {
  465. delete pMsg;
  466. return 0;
  467. }
  468. int nEvent=pMsg->lEvent&0xFFFF;
  469. int nErrorCode=pMsg->lEvent>>16;
  470. //Dispatch to layer
  471. if (pMsg->pLayer)
  472. {
  473. pMsg->pLayer->CallEvent(nEvent, nErrorCode);
  474. }
  475. else
  476. {
  477. //Dispatch to CAsyncSocketEx instance
  478. switch (nEvent)
  479. {
  480. case FD_READ:
  481. #ifndef NOSOCKETSTATES
  482. if (pSocket->GetState() == connecting && !nErrorCode)
  483. {
  484. pSocket->m_nPendingEvents |= FD_READ;
  485. break;
  486. }
  487. else if (pSocket->GetState() == attached && !nErrorCode)
  488. pSocket->SetState(connected);
  489. if (pSocket->GetState() != connected)
  490. break;
  491. #endif //NOSOCKETSTATES
  492. if (pSocket->m_lEvent & FD_READ)
  493. {
  494. #ifndef NOSOCKETSTATES
  495. if (nErrorCode)
  496. pSocket->SetState(aborted);
  497. #endif //NOSOCKETSTATES
  498. pSocket->OnReceive(nErrorCode);
  499. }
  500. break;
  501. case FD_FORCEREAD: //Forceread does not check if there's data waiting
  502. #ifndef NOSOCKETSTATES
  503. if (pSocket->GetState() == connecting && !nErrorCode)
  504. {
  505. pSocket->m_nPendingEvents |= FD_FORCEREAD;
  506. break;
  507. }
  508. else if (pSocket->GetState() == attached && !nErrorCode)
  509. pSocket->SetState(connected);
  510. if (pSocket->GetState() != connected)
  511. break;
  512. #endif //NOSOCKETSTATES
  513. if (pSocket->m_lEvent & FD_READ)
  514. {
  515. #ifndef NOSOCKETSTATES
  516. if (nErrorCode)
  517. pSocket->SetState(aborted);
  518. #endif //NOSOCKETSTATES
  519. pSocket->OnReceive(nErrorCode);
  520. }
  521. break;
  522. case FD_WRITE:
  523. #ifndef NOSOCKETSTATES
  524. if (pSocket->GetState() == connecting && !nErrorCode)
  525. {
  526. pSocket->m_nPendingEvents |= FD_WRITE;
  527. break;
  528. }
  529. else if (pSocket->GetState() == attached && !nErrorCode)
  530. pSocket->SetState(connected);
  531. if (pSocket->GetState() != connected)
  532. break;
  533. #endif //NOSOCKETSTATES
  534. if (pSocket->m_lEvent & FD_WRITE)
  535. {
  536. #ifndef NOSOCKETSTATES
  537. if (nErrorCode)
  538. pSocket->SetState(aborted);
  539. #endif //NOSOCKETSTATES
  540. pSocket->OnSend(nErrorCode);
  541. }
  542. break;
  543. case FD_CONNECT:
  544. #ifndef NOSOCKETSTATES
  545. if (pSocket->GetState() == connecting)
  546. pSocket->SetState(connected);
  547. else if (pSocket->GetState() == attached && !nErrorCode)
  548. pSocket->SetState(connected);
  549. #endif //NOSOCKETSTATES
  550. if (pSocket->m_lEvent & FD_CONNECT)
  551. pSocket->OnConnect(nErrorCode);
  552. #ifndef NOSOCKETSTATES
  553. if (!nErrorCode)
  554. {
  555. if (((pSocket->m_nPendingEvents&FD_READ) && pSocket->GetState() == connected) && (pSocket->m_lEvent & FD_READ))
  556. pSocket->OnReceive(0);
  557. if (((pSocket->m_nPendingEvents&FD_FORCEREAD) && pSocket->GetState() == connected) && (pSocket->m_lEvent & FD_READ))
  558. pSocket->OnReceive(0);
  559. if (((pSocket->m_nPendingEvents&FD_WRITE) && pSocket->GetState() == connected) && (pSocket->m_lEvent & FD_WRITE))
  560. pSocket->OnSend(0);
  561. }
  562. pSocket->m_nPendingEvents = 0;
  563. #endif //NOSOCKETSTATES
  564. break;
  565. case FD_ACCEPT:
  566. #ifndef NOSOCKETSTATES
  567. if ((pSocket->GetState() == listening || pSocket->GetState() == attached) && (pSocket->m_lEvent & FD_ACCEPT))
  568. #endif //NOSOCKETSTATES
  569. {
  570. pSocket->OnAccept(nErrorCode);
  571. }
  572. break;
  573. case FD_CLOSE:
  574. #ifndef NOSOCKETSTATES
  575. if ((pSocket->GetState() == connected || pSocket->GetState() == attached) && (pSocket->m_lEvent & FD_CLOSE))
  576. {
  577. pSocket->SetState(nErrorCode?aborted:closed);
  578. #else
  579. {
  580. #endif //NOSOCKETSTATES
  581. pSocket->OnClose(nErrorCode);
  582. }
  583. break;
  584. }
  585. }
  586. delete pMsg;
  587. return 0;
  588. }
  589. #endif //NOLAYERS
  590. else if (message == WM_USER+1)
  591. {
  592. ASSERT(pWnd);
  593. // WSAAsyncGetHostByName reply
  594. // Verify parameters
  595. ASSERT(hWnd);
  596. CAsyncSocketExHelperWindow *pWnd = (CAsyncSocketExHelperWindow *)GetWindowLongPtr(hWnd, GWL_USERDATA);
  597. ASSERT(pWnd);
  598. CAsyncSocketEx *pSocket = NULL;
  599. for (int i = 0; i < pWnd->m_nWindowDataSize; i++)
  600. {
  601. pSocket = pWnd->m_pAsyncSocketExWindowData[i].m_pSocket;
  602. if (pSocket && pSocket->m_hAsyncGetHostByNameHandle &&
  603. pSocket->m_hAsyncGetHostByNameHandle == (HANDLE)wParam)
  604. break;
  605. }
  606. if (!pSocket)
  607. return 0;
  608. int nErrorCode = lParam >> 16;
  609. if (nErrorCode)
  610. {
  611. pSocket->OnConnect(nErrorCode);
  612. return 0;
  613. }
  614. SOCKADDR_IN sockAddr;
  615. memset(&sockAddr,0,sizeof(sockAddr));
  616. sockAddr.sin_family=AF_INET;
  617. sockAddr.sin_addr.s_addr = ((LPIN_ADDR)((LPHOSTENT)pSocket->m_pAsyncGetHostByNameBuffer)->h_addr)->s_addr;
  618. sockAddr.sin_port = htons(pSocket->m_nAsyncGetHostByNamePort);
  619. BOOL res = pSocket->Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  620. delete [] pSocket->m_pAsyncGetHostByNameBuffer;
  621. pSocket->m_pAsyncGetHostByNameBuffer=0;
  622. pSocket->m_hAsyncGetHostByNameHandle=0;
  623. if (!res)
  624. if (GetLastError()!=WSAEWOULDBLOCK)
  625. pSocket->OnConnect(GetLastError());
  626. return 0;
  627. }
  628. else if (message == WM_USER + 2)
  629. {
  630. ASSERT(pWnd);
  631. if (wParam >= static_cast<UINT>(pWnd->m_nWindowDataSize)) //Index is within socket storage
  632. return 0;
  633. CAsyncSocketEx *pSocket = pWnd->m_pAsyncSocketExWindowData[wParam].m_pSocket;
  634. if (!pSocket)
  635. return 0;
  636. // Process pending callbacks
  637. std::list<t_callbackMsg> tmp;
  638. tmp.swap(pSocket->m_pendingCallbacks);
  639. pSocket->OnLayerCallback(tmp);
  640. }
  641. else if (message == WM_TIMER)
  642. {
  643. ASSERT(pWnd);
  644. if (wParam != 1)
  645. return 0;
  646. if (pWnd->m_pThreadData->layerCloseNotify.empty())
  647. {
  648. KillTimer(hWnd, 1);
  649. return 0;
  650. }
  651. CAsyncSocketEx* socket = pWnd->m_pThreadData->layerCloseNotify.front();
  652. pWnd->m_pThreadData->layerCloseNotify.pop_front();
  653. if (pWnd->m_pThreadData->layerCloseNotify.empty())
  654. KillTimer(hWnd, 1);
  655. PostMessage(hWnd, socket->m_SocketData.nSocketIndex + WM_SOCKETEX_NOTIFY, socket->m_SocketData.hSocket, FD_CLOSE);
  656. return 0;
  657. }
  658. return DefWindowProc(hWnd, message, wParam, lParam);
  659. }
  660. HWND GetHwnd()
  661. {
  662. return m_hWnd;
  663. }
  664. private:
  665. HWND m_hWnd;
  666. struct t_AsyncSocketExWindowData
  667. {
  668. CAsyncSocketEx *m_pSocket;
  669. } *m_pAsyncSocketExWindowData;
  670. int m_nWindowDataSize;
  671. int m_nWindowDataPos;
  672. int m_nSocketCount;
  673. CAsyncSocketEx::t_AsyncSocketExThreadData* m_pThreadData;
  674. };
  675. //////////////////////////////////////////////////////////////////////
  676. // Konstruktion/Destruktion
  677. //////////////////////////////////////////////////////////////////////
  678. CAsyncSocketEx::CAsyncSocketEx()
  679. {
  680. m_SocketData.hSocket = INVALID_SOCKET;
  681. m_SocketData.nSocketIndex = -1;
  682. m_SocketData.nFamily = AF_UNSPEC;
  683. m_SocketData.onCloseCalled = false;
  684. m_pLocalAsyncSocketExThreadData = 0;
  685. #ifndef NOSOCKETSTATES
  686. m_nPendingEvents = 0;
  687. m_nState = notsock;
  688. #endif //NOSOCKETSTATES
  689. #ifndef NOLAYERS
  690. m_pFirstLayer = 0;
  691. m_pLastLayer = 0;
  692. #endif //NOLAYERS
  693. m_lEvent = 0;
  694. m_pAsyncGetHostByNameBuffer = NULL;
  695. m_hAsyncGetHostByNameHandle = NULL;
  696. m_nAsyncGetHostByNamePort = 0;
  697. m_nSocketPort = 0;
  698. m_lpszSocketAddress = 0;
  699. m_SocketData.addrInfo = 0;
  700. m_SocketData.nextAddr = 0;
  701. }
  702. CAsyncSocketEx::~CAsyncSocketEx()
  703. {
  704. Close();
  705. FreeAsyncSocketExInstance();
  706. }
  707. BOOL CAsyncSocketEx::Create(UINT nSocketPort /*=0*/, int nSocketType /*=SOCK_STREAM*/, long lEvent /*=FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/, LPCTSTR lpszSocketAddress /*=NULL*/, int nFamily /*=AF_INET*/)
  708. {
  709. ASSERT(GetSocketHandle() == INVALID_SOCKET);
  710. //Close the socket, although this should not happen
  711. if (GetSocketHandle() != INVALID_SOCKET)
  712. {
  713. WSASetLastError(WSAEALREADY);
  714. return FALSE;
  715. }
  716. BOOL res = InitAsyncSocketExInstance();
  717. ASSERT(res);
  718. if (!res)
  719. {
  720. WSASetLastError(WSANOTINITIALISED);
  721. return FALSE;
  722. }
  723. m_SocketData.nFamily = nFamily;
  724. #ifndef NOLAYERS
  725. if (m_pFirstLayer)
  726. {
  727. BOOL res = m_pFirstLayer->Create(nSocketPort, nSocketType, lEvent, lpszSocketAddress, nFamily);
  728. #ifndef NOSOCKETSTATES
  729. if (res)
  730. SetState(unconnected);
  731. #endif //NOSOCKETSTATES
  732. return res;
  733. }
  734. else
  735. #endif //NOLAYERS
  736. {
  737. if (m_SocketData.nFamily == AF_UNSPEC)
  738. {
  739. #ifndef NOSOCKETSTATES
  740. SetState(unconnected);
  741. #endif //NOSOCKETSTATES
  742. m_lEvent = lEvent;
  743. m_nSocketPort = nSocketPort;
  744. delete [] m_lpszSocketAddress;
  745. if (lpszSocketAddress && *lpszSocketAddress)
  746. {
  747. m_lpszSocketAddress = new TCHAR[_tcslen(lpszSocketAddress) + 1];
  748. _tcscpy(m_lpszSocketAddress, lpszSocketAddress);
  749. }
  750. else
  751. m_lpszSocketAddress = 0;
  752. return TRUE;
  753. }
  754. else
  755. {
  756. SOCKET hSocket = socket(m_SocketData.nFamily, nSocketType, 0);
  757. if (hSocket == INVALID_SOCKET)
  758. return FALSE;
  759. m_SocketData.hSocket = hSocket;
  760. AttachHandle(hSocket);
  761. #ifndef NOLAYERS
  762. if (m_pFirstLayer)
  763. {
  764. m_lEvent = lEvent;
  765. if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) )
  766. {
  767. Close();
  768. return FALSE;
  769. }
  770. }
  771. else
  772. #endif //NOLAYERS
  773. {
  774. if (!AsyncSelect(lEvent))
  775. {
  776. Close();
  777. return FALSE;
  778. }
  779. }
  780. if (!Bind(nSocketPort, lpszSocketAddress))
  781. {
  782. Close();
  783. return FALSE;
  784. }
  785. #ifndef NOSOCKETSTATES
  786. SetState(unconnected);
  787. #endif //NOSOCKETSTATES
  788. return TRUE;
  789. }
  790. }
  791. }
  792. void CAsyncSocketEx::OnReceive(int nErrorCode)
  793. {
  794. }
  795. void CAsyncSocketEx::OnSend(int nErrorCode)
  796. {
  797. }
  798. void CAsyncSocketEx::OnConnect(int nErrorCode)
  799. {
  800. }
  801. void CAsyncSocketEx::OnAccept(int nErrorCode)
  802. {
  803. }
  804. void CAsyncSocketEx::OnClose(int nErrorCode)
  805. {
  806. }
  807. BOOL CAsyncSocketEx::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
  808. {
  809. delete [] m_lpszSocketAddress;
  810. if (lpszSocketAddress && *lpszSocketAddress)
  811. {
  812. m_lpszSocketAddress = new TCHAR[_tcslen(lpszSocketAddress) + 1];
  813. _tcscpy(m_lpszSocketAddress, lpszSocketAddress);
  814. }
  815. else
  816. m_lpszSocketAddress = 0;
  817. m_nSocketPort = nSocketPort;
  818. if (m_SocketData.nFamily == AF_UNSPEC)
  819. return TRUE;
  820. USES_CONVERSION;
  821. LPSTR lpszAscii = (lpszSocketAddress && *lpszSocketAddress) ? T2A((LPTSTR)lpszSocketAddress) : 0;
  822. if ((m_SocketData.nFamily == AF_INET6 || m_SocketData.nFamily == AF_INET) && lpszAscii)
  823. {
  824. addrinfo hints, *res0, *res;
  825. int error;
  826. char port[10];
  827. BOOL ret = FALSE;
  828. memset(&hints, 0, sizeof(addrinfo));
  829. hints.ai_family = m_SocketData.nFamily;
  830. hints.ai_socktype = SOCK_STREAM;
  831. _snprintf(port, 9, "%lu", nSocketPort);
  832. error = getaddrinfo(lpszAscii, port, &hints, &res0);
  833. if (error)
  834. return FALSE;
  835. for (res = res0; res; res = res->ai_next)
  836. if (Bind(res->ai_addr, res->ai_addrlen))
  837. {
  838. ret = TRUE;
  839. break;
  840. }
  841. else
  842. continue ;
  843. freeaddrinfo(res0);
  844. return ret ;
  845. }
  846. else if (!lpszAscii && m_SocketData.nFamily == AF_INET6)
  847. {
  848. SOCKADDR_IN6 sockAddr6;
  849. memset(&sockAddr6, 0, sizeof(sockAddr6));
  850. sockAddr6.sin6_family = AF_INET6 ;
  851. sockAddr6.sin6_addr = in6addr_any ;
  852. sockAddr6.sin6_port = htons((u_short)nSocketPort);
  853. return Bind((SOCKADDR*)&sockAddr6, sizeof(sockAddr6));
  854. }
  855. else if (!lpszAscii && m_SocketData.nFamily == AF_INET)
  856. {
  857. SOCKADDR_IN sockAddr;
  858. memset(&sockAddr, 0, sizeof(sockAddr));
  859. sockAddr.sin_family = AF_INET ;
  860. sockAddr.sin_addr.s_addr = INADDR_ANY ;
  861. sockAddr.sin_port = htons((u_short)nSocketPort);
  862. return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  863. }
  864. else
  865. return FALSE ;
  866. }
  867. BOOL CAsyncSocketEx::Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  868. {
  869. if (!bind(m_SocketData.hSocket, lpSockAddr, nSockAddrLen))
  870. return TRUE;
  871. else
  872. return FALSE;
  873. }
  874. void CAsyncSocketEx::AttachHandle(SOCKET hSocket)
  875. {
  876. ASSERT(m_pLocalAsyncSocketExThreadData);
  877. VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->AddSocket(this, m_SocketData.nSocketIndex));
  878. #ifndef NOSOCKETSTATES
  879. SetState(attached);
  880. #endif //NOSOCKETSTATES
  881. }
  882. void CAsyncSocketEx::DetachHandle(SOCKET hSocket)
  883. {
  884. ASSERT(m_pLocalAsyncSocketExThreadData);
  885. if (!m_pLocalAsyncSocketExThreadData)
  886. return;
  887. ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
  888. if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  889. return;
  890. VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->RemoveSocket(this, m_SocketData.nSocketIndex));
  891. #ifndef NOSOCKETSTATES
  892. SetState(notsock);
  893. #endif //NOSOCKETSTATES
  894. }
  895. void CAsyncSocketEx::Close()
  896. {
  897. #ifndef NOSOCKETSTATES
  898. m_nPendingEvents = 0;
  899. #endif //NOSOCKETSTATES
  900. #ifndef NOLAYERS
  901. if (m_pFirstLayer)
  902. m_pFirstLayer->Close();
  903. #endif //NOLAYERS
  904. if (m_SocketData.hSocket != INVALID_SOCKET)
  905. {
  906. VERIFY((closesocket(m_SocketData.hSocket) != SOCKET_ERROR));
  907. DetachHandle(m_SocketData.hSocket);
  908. m_SocketData.hSocket = INVALID_SOCKET;
  909. }
  910. if (m_SocketData.addrInfo)
  911. {
  912. freeaddrinfo(m_SocketData.addrInfo);
  913. m_SocketData.addrInfo = 0;
  914. m_SocketData.nextAddr = 0;
  915. }
  916. m_SocketData.nFamily = AF_UNSPEC;
  917. delete [] m_lpszSocketAddress;
  918. m_lpszSocketAddress = 0;
  919. m_nSocketPort = 0;
  920. #ifndef NOLAYERS
  921. RemoveAllLayers();
  922. #endif //NOLAYERS
  923. delete [] m_pAsyncGetHostByNameBuffer;
  924. m_pAsyncGetHostByNameBuffer = NULL;
  925. if (m_hAsyncGetHostByNameHandle)
  926. WSACancelAsyncRequest(m_hAsyncGetHostByNameHandle);
  927. m_hAsyncGetHostByNameHandle = NULL;
  928. m_SocketData.onCloseCalled = false;
  929. }
  930. BOOL CAsyncSocketEx::InitAsyncSocketExInstance()
  931. {
  932. //Check if already initialized
  933. if (m_pLocalAsyncSocketExThreadData)
  934. return TRUE;
  935. DWORD id=GetCurrentThreadId();
  936. m_sGlobalCriticalSection.Lock();
  937. //Get thread specific data
  938. if (m_spAsyncSocketExThreadDataList)
  939. {
  940. t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
  941. while (pList)
  942. {
  943. ASSERT(pList->pThreadData);
  944. ASSERT(pList->pThreadData->nInstanceCount>0);
  945. if (pList->pThreadData->nThreadId==id)
  946. {
  947. m_pLocalAsyncSocketExThreadData=pList->pThreadData;
  948. m_pLocalAsyncSocketExThreadData->nInstanceCount++;
  949. break;
  950. }
  951. pList=pList->pNext;
  952. }
  953. //Current thread yet has no sockets
  954. if (!pList)
  955. {
  956. //Initialize data for current thread
  957. pList=new t_AsyncSocketExThreadDataList;
  958. pList->pNext=m_spAsyncSocketExThreadDataList;
  959. m_spAsyncSocketExThreadDataList=pList;
  960. m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
  961. m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
  962. m_pLocalAsyncSocketExThreadData->nThreadId=id;
  963. m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow(m_pLocalAsyncSocketExThreadData);
  964. m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
  965. }
  966. }
  967. else
  968. { //No thread has instances of CAsyncSocketEx; Initialize data
  969. m_spAsyncSocketExThreadDataList=new t_AsyncSocketExThreadDataList;
  970. m_spAsyncSocketExThreadDataList->pNext=0;
  971. m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
  972. m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
  973. m_pLocalAsyncSocketExThreadData->nThreadId=id;
  974. m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow(m_pLocalAsyncSocketExThreadData);
  975. m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
  976. }
  977. m_sGlobalCriticalSection.Unlock();
  978. return TRUE;
  979. }
  980. void CAsyncSocketEx::FreeAsyncSocketExInstance()
  981. {
  982. //Check if already freed
  983. if (!m_pLocalAsyncSocketExThreadData)
  984. return;
  985. for (std::list<CAsyncSocketEx*>::iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); iter++)
  986. {
  987. if (*iter != this)
  988. continue;
  989. m_pLocalAsyncSocketExThreadData->layerCloseNotify.erase(iter);
  990. if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.empty())
  991. KillTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1);
  992. break;
  993. }
  994. DWORD id=m_pLocalAsyncSocketExThreadData->nThreadId;
  995. m_sGlobalCriticalSection.Lock();
  996. ASSERT(m_spAsyncSocketExThreadDataList);
  997. t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
  998. t_AsyncSocketExThreadDataList *pPrev=0;
  999. //Serach for data for current thread and decrease instance count
  1000. while (pList)
  1001. {
  1002. ASSERT(pList->pThreadData);
  1003. ASSERT(pList->pThreadData->nInstanceCount>0);
  1004. if (pList->pThreadData->nThreadId==id)
  1005. {
  1006. ASSERT(m_pLocalAsyncSocketExThreadData==pList->pThreadData);
  1007. m_pLocalAsyncSocketExThreadData->nInstanceCount--;
  1008. //Freeing last instance?
  1009. //If so, destroy helper window
  1010. if (!m_pLocalAsyncSocketExThreadData->nInstanceCount)
  1011. {
  1012. delete m_pLocalAsyncSocketExThreadData->m_pHelperWindow;
  1013. delete m_pLocalAsyncSocketExThreadData;
  1014. if (pPrev)
  1015. pPrev->pNext=pList->pNext;
  1016. else
  1017. m_spAsyncSocketExThreadDataList=pList->pNext;
  1018. delete pList;
  1019. break;
  1020. }
  1021. break;
  1022. }
  1023. pPrev=pList;
  1024. pList=pList->pNext;
  1025. ASSERT(pList);
  1026. }
  1027. m_sGlobalCriticalSection.Unlock();
  1028. }
  1029. int CAsyncSocketEx::Receive(void* lpBuf, int nBufLen, int nFlags /*=0*/)
  1030. {
  1031. #ifndef NOLAYERS
  1032. if (m_pFirstLayer)
  1033. return m_pFirstLayer->Receive(lpBuf, nBufLen, nFlags);
  1034. else
  1035. #endif //NOLAYERS
  1036. return recv(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  1037. }
  1038. int CAsyncSocketEx::Send(const void* lpBuf, int nBufLen, int nFlags /*=0*/)
  1039. {
  1040. #ifndef NOLAYERS
  1041. if (m_pFirstLayer)
  1042. return m_pFirstLayer->Send(lpBuf, nBufLen, nFlags);
  1043. else
  1044. #endif //NOLAYERS
  1045. return send(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  1046. }
  1047. BOOL CAsyncSocketEx::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
  1048. {
  1049. #ifndef NOLAYERS
  1050. if (m_pFirstLayer)
  1051. {
  1052. BOOL res = m_pFirstLayer->Connect(lpszHostAddress, nHostPort);
  1053. #ifndef NOSOCKETSTATES
  1054. if (res || GetLastError()==WSAEWOULDBLOCK)
  1055. SetState(connecting);
  1056. #endif //NOSOCKETSTATES
  1057. return res;
  1058. } else
  1059. #endif //NOLAYERS
  1060. if (m_SocketData.nFamily == AF_INET)
  1061. {
  1062. USES_CONVERSION;
  1063. ASSERT(lpszHostAddress != NULL);
  1064. SOCKADDR_IN sockAddr;
  1065. memset(&sockAddr,0,sizeof(sockAddr));
  1066. LPSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  1067. sockAddr.sin_family = AF_INET;
  1068. sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  1069. if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  1070. {
  1071. if (m_pAsyncGetHostByNameBuffer)
  1072. delete [] m_pAsyncGetHostByNameBuffer;
  1073. m_pAsyncGetHostByNameBuffer=new char[MAXGETHOSTSTRUCT];
  1074. m_nAsyncGetHostByNamePort=nHostPort;
  1075. m_hAsyncGetHostByNameHandle=WSAAsyncGetHostByName(GetHelperWindowHandle(), WM_USER+1, lpszAscii, m_pAsyncGetHostByNameBuffer, MAXGETHOSTSTRUCT);
  1076. if (!m_hAsyncGetHostByNameHandle)
  1077. return FALSE;
  1078. WSASetLastError(WSAEWOULDBLOCK);
  1079. #ifndef NOSOCKETSTATES
  1080. SetState(connecting);
  1081. #endif //NOSOCKETSTATES
  1082. return FALSE;
  1083. }
  1084. sockAddr.sin_port = htons((u_short)nHostPort);
  1085. return CAsyncSocketEx::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  1086. }
  1087. else
  1088. {
  1089. USES_CONVERSION;
  1090. ASSERT( lpszHostAddress != NULL );
  1091. if (m_SocketData.addrInfo)
  1092. {
  1093. freeaddrinfo(m_SocketData.addrInfo);
  1094. m_SocketData.addrInfo = 0;
  1095. m_SocketData.nextAddr = 0;
  1096. }
  1097. addrinfo hints;
  1098. int error;
  1099. BOOL ret;
  1100. char port[10];
  1101. memset(&hints, 0, sizeof(addrinfo));
  1102. hints.ai_family = m_SocketData.nFamily;
  1103. hints.ai_socktype = SOCK_STREAM;
  1104. _snprintf(port, 9, "%lu", nHostPort);
  1105. error = getaddrinfo(T2CA(lpszHostAddress), port, &hints, &m_SocketData.addrInfo);
  1106. if (error)
  1107. return FALSE;
  1108. for (m_SocketData.nextAddr = m_SocketData.addrInfo; m_SocketData.nextAddr; m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next)
  1109. {
  1110. bool newSocket = false;
  1111. if (m_SocketData.nFamily == AF_UNSPEC)
  1112. {
  1113. newSocket = true;
  1114. m_SocketData.hSocket = socket(m_SocketData.nextAddr->ai_family, m_SocketData.nextAddr->ai_socktype, m_SocketData.nextAddr->ai_protocol);
  1115. if (m_SocketData.hSocket == INVALID_SOCKET)
  1116. continue;
  1117. m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1118. AttachHandle(m_SocketData.hSocket);
  1119. if (!AsyncSelect(m_lEvent))
  1120. {
  1121. if (newSocket)
  1122. {
  1123. DetachHandle(m_SocketData.hSocket);
  1124. closesocket(m_SocketData.hSocket);
  1125. m_SocketData.hSocket = INVALID_SOCKET;
  1126. }
  1127. continue;
  1128. }
  1129. }
  1130. else if (m_SocketData.hSocket == INVALID_SOCKET)
  1131. continue;
  1132. #ifndef NOLAYERS
  1133. if (m_pFirstLayer)
  1134. {
  1135. if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1136. {
  1137. if (newSocket)
  1138. {
  1139. m_SocketData.nFamily = AF_UNSPEC;
  1140. DetachHandle(m_SocketData.hSocket);
  1141. closesocket(m_SocketData.hSocket);
  1142. m_SocketData.hSocket = INVALID_SOCKET;
  1143. }
  1144. continue;
  1145. }
  1146. }
  1147. #endif //NOLAYERS
  1148. if (newSocket)
  1149. {
  1150. m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1151. if (!Bind(m_nSocketPort, m_lpszSocketAddress))
  1152. {
  1153. m_SocketData.nFamily = AF_UNSPEC;
  1154. DetachHandle(m_SocketData.hSocket);
  1155. closesocket(m_SocketData.hSocket);
  1156. m_SocketData.hSocket = INVALID_SOCKET;
  1157. continue;
  1158. }
  1159. }
  1160. if (!(ret = CAsyncSocketEx::Connect(m_SocketData.nextAddr->ai_addr, m_SocketData.nextAddr->ai_addrlen)) && GetLastError() != WSAEWOULDBLOCK)
  1161. {
  1162. if (newSocket)
  1163. {
  1164. m_SocketData.nFamily = AF_UNSPEC;
  1165. DetachHandle(m_SocketData.hSocket);
  1166. closesocket(m_SocketData.hSocket);
  1167. m_SocketData.hSocket = INVALID_SOCKET;
  1168. }
  1169. continue;
  1170. }
  1171. break;
  1172. }
  1173. if (m_SocketData.nextAddr)
  1174. m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next;
  1175. if (!m_SocketData.nextAddr)
  1176. {
  1177. freeaddrinfo(m_SocketData.addrInfo);
  1178. m_SocketData.nextAddr = 0;
  1179. m_SocketData.addrInfo = 0;
  1180. }
  1181. if (m_SocketData.hSocket == INVALID_SOCKET || !ret)
  1182. return FALSE;
  1183. else
  1184. return TRUE;
  1185. }
  1186. }
  1187. BOOL CAsyncSocketEx::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  1188. {
  1189. BOOL res;
  1190. #ifndef NOLAYERS
  1191. if (m_pFirstLayer)
  1192. res = SOCKET_ERROR!=m_pFirstLayer->Connect(lpSockAddr, nSockAddrLen);
  1193. else
  1194. #endif //NOLAYERS
  1195. res = SOCKET_ERROR!=connect(m_SocketData.hSocket, lpSockAddr, nSockAddrLen);
  1196. #ifndef NOSOCKETSTATES
  1197. if (res || GetLastError()==WSAEWOULDBLOCK)
  1198. SetState(connecting);
  1199. #endif //NOSOCKETSTATES
  1200. return res;
  1201. }
  1202. #ifdef _AFX
  1203. BOOL CAsyncSocketEx::GetPeerName( CString& rPeerAddress, UINT& rPeerPort )
  1204. {
  1205. #ifndef NOLAYERS
  1206. if (m_pFirstLayer)
  1207. return m_pFirstLayer->GetPeerName(rPeerAddress, rPeerPort);
  1208. #endif NOLAYERS
  1209. SOCKADDR* sockAddr;
  1210. int nSockAddrLen;
  1211. if (m_SocketData.nFamily == AF_INET6)
  1212. {
  1213. sockAddr = (SOCKADDR*)new SOCKADDR_IN6;
  1214. nSockAddrLen = sizeof(SOCKADDR_IN6);
  1215. }
  1216. else if (m_SocketData.nFamily == AF_INET)
  1217. {
  1218. sockAddr = (SOCKADDR*)new SOCKADDR_IN;
  1219. nSockAddrLen = sizeof(SOCKADDR_IN);
  1220. }
  1221. memset(sockAddr, 0, nSockAddrLen);
  1222. BOOL bResult = GetPeerName(sockAddr, &nSockAddrLen);
  1223. if (bResult)
  1224. {
  1225. if (m_SocketData.nFamily == AF_INET6)
  1226. {
  1227. rPeerPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);
  1228. LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);
  1229. rPeerAddress = buf;
  1230. delete [] buf;
  1231. }
  1232. else if (m_SocketData.nFamily == AF_INET)
  1233. {
  1234. rPeerPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);
  1235. rPeerAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);
  1236. }
  1237. else
  1238. {
  1239. delete sockAddr;
  1240. return FALSE;
  1241. }
  1242. }
  1243. delete sockAddr;
  1244. return bResult;
  1245. }
  1246. #endif //_AFX
  1247. BOOL CAsyncSocketEx::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1248. {
  1249. #ifndef NOLAYERS
  1250. if (m_pFirstLayer)
  1251. return m_pFirstLayer->GetPeerName(lpSockAddr, lpSockAddrLen);
  1252. #endif //NOLAYERS
  1253. if (!getpeername(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen))
  1254. {
  1255. return TRUE;
  1256. }
  1257. else
  1258. {
  1259. return FALSE;
  1260. }
  1261. }
  1262. #ifdef _AFX
  1263. BOOL CAsyncSocketEx::GetSockName(CString& rSocketAddress, UINT& rSocketPort)
  1264. {
  1265. SOCKADDR* sockAddr;
  1266. int nSockAddrLen;
  1267. if (m_SocketData.nFamily == AF_INET6)
  1268. {
  1269. sockAddr = (SOCKADDR*)new SOCKADDR_IN6;
  1270. nSockAddrLen = sizeof(SOCKADDR_IN6);
  1271. }
  1272. else if (m_SocketData.nFamily == AF_INET)
  1273. {
  1274. sockAddr = (SOCKADDR*)new SOCKADDR_IN;
  1275. nSockAddrLen = sizeof(SOCKADDR_IN);
  1276. }
  1277. memset(sockAddr, 0, nSockAddrLen);
  1278. BOOL bResult = GetSockName(sockAddr, &nSockAddrLen);
  1279. if (bResult)
  1280. {
  1281. if (m_SocketData.nFamily == AF_INET6)
  1282. {
  1283. rSocketPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);
  1284. LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);
  1285. rSocketAddress = buf;
  1286. delete [] buf;
  1287. }
  1288. else if (m_SocketData.nFamily == AF_INET)
  1289. {
  1290. rSocketPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);
  1291. rSocketAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);
  1292. }
  1293. else
  1294. {
  1295. delete sockAddr;
  1296. return FALSE;
  1297. }
  1298. }
  1299. delete sockAddr;
  1300. return bResult;
  1301. }
  1302. #endif //_AFX
  1303. BOOL CAsyncSocketEx::GetSockName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1304. {
  1305. if ( !getsockname(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen) )
  1306. return TRUE;
  1307. else
  1308. return FALSE;
  1309. }
  1310. BOOL CAsyncSocketEx::ShutDown(int nHow /*=sends*/)
  1311. {
  1312. #ifndef NOLAYERS
  1313. if (m_pFirstLayer)
  1314. {
  1315. return m_pFirstLayer->ShutDown();
  1316. }
  1317. else
  1318. #endif //NOLAYERS
  1319. {
  1320. if (!shutdown(m_SocketData.hSocket, nHow))
  1321. return TRUE;
  1322. else
  1323. return FALSE;
  1324. }
  1325. }
  1326. SOCKET CAsyncSocketEx::Detach()
  1327. {
  1328. SOCKET socket = m_SocketData.hSocket;
  1329. DetachHandle(socket);
  1330. m_SocketData.hSocket = INVALID_SOCKET;
  1331. m_SocketData.nFamily = AF_UNSPEC;
  1332. return socket;
  1333. }
  1334. BOOL CAsyncSocketEx::Attach(SOCKET hSocket, long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/)
  1335. {
  1336. if (hSocket==INVALID_SOCKET || !hSocket)
  1337. return FALSE;
  1338. VERIFY(InitAsyncSocketExInstance());
  1339. m_SocketData.hSocket=hSocket;
  1340. AttachHandle(hSocket);
  1341. #ifndef NOLAYERS
  1342. if (m_pFirstLayer)
  1343. {
  1344. m_lEvent = lEvent;
  1345. return !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
  1346. }
  1347. else
  1348. #endif //NOLAYERS
  1349. {
  1350. return AsyncSelect(lEvent);
  1351. }
  1352. }
  1353. BOOL CAsyncSocketEx::AsyncSelect( long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/ )
  1354. {
  1355. ASSERT(m_pLocalAsyncSocketExThreadData);
  1356. m_lEvent = lEvent;
  1357. #ifndef NOLAYERS
  1358. if (m_pFirstLayer)
  1359. return TRUE;
  1360. else
  1361. #endif //NOLAYERS
  1362. {
  1363. if (m_SocketData.hSocket == INVALID_SOCKET && m_SocketData.nFamily == AF_UNSPEC)
  1364. return true;
  1365. if ( !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, lEvent) )
  1366. return TRUE;
  1367. else
  1368. return FALSE;
  1369. }
  1370. return TRUE;
  1371. }
  1372. BOOL CAsyncSocketEx::Listen( int nConnectionBacklog /*=5*/ )
  1373. {
  1374. #ifndef NOLAYERS
  1375. if (m_pFirstLayer)
  1376. return m_pFirstLayer->Listen(nConnectionBacklog);
  1377. #endif //NOLAYERS
  1378. if (!listen(m_SocketData.hSocket, nConnectionBacklog))
  1379. {
  1380. #ifndef NOSOCKETSTATES
  1381. SetState(listening);
  1382. #endif //NOSOCKETSTATES
  1383. return TRUE;
  1384. }
  1385. else
  1386. return FALSE;
  1387. }
  1388. BOOL CAsyncSocketEx::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  1389. {
  1390. ASSERT(rConnectedSocket.m_SocketData.hSocket == INVALID_SOCKET);
  1391. #ifndef NOLAYERS
  1392. if (m_pFirstLayer)
  1393. {
  1394. return m_pFirstLayer->Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  1395. }
  1396. else
  1397. #endif //NOLAYERS
  1398. {
  1399. SOCKET hTemp = accept(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen);
  1400. if (hTemp == INVALID_SOCKET)
  1401. return FALSE;
  1402. VERIFY(rConnectedSocket.InitAsyncSocketExInstance());
  1403. rConnectedSocket.m_SocketData.hSocket=hTemp;
  1404. rConnectedSocket.AttachHandle(hTemp);
  1405. rConnectedSocket.SetFamily(GetFamily());
  1406. #ifndef NOSOCKETSTATES
  1407. rConnectedSocket.SetState(connected);
  1408. #endif //NOSOCKETSTATES
  1409. }
  1410. return TRUE;
  1411. }
  1412. BOOL CAsyncSocketEx::IOCtl( long lCommand, DWORD* lpArgument )
  1413. {
  1414. return ioctlsocket(m_SocketData.hSocket, lCommand, lpArgument) != SOCKET_ERROR;
  1415. }
  1416. int CAsyncSocketEx::GetLastError()
  1417. {
  1418. return WSAGetLastError();
  1419. }
  1420. BOOL CAsyncSocketEx::TriggerEvent(long lEvent)
  1421. {
  1422. if (m_SocketData.hSocket==INVALID_SOCKET)
  1423. return FALSE;
  1424. ASSERT(m_pLocalAsyncSocketExThreadData);
  1425. ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
  1426. ASSERT(m_SocketData.nSocketIndex!=-1);
  1427. #ifndef NOLAYERS
  1428. if (m_pFirstLayer)
  1429. {
  1430. CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg = new CAsyncSocketExLayer::t_LayerNotifyMsg;
  1431. pMsg->hSocket = m_SocketData.hSocket;
  1432. pMsg->lEvent=lEvent%0xFFFF;
  1433. pMsg->pLayer=0;
  1434. BOOL res=PostMessage(GetHelperWindowHandle(), WM_USER, (WPARAM)m_SocketData.nSocketIndex, (LPARAM)pMsg);
  1435. if (!res)
  1436. delete pMsg;
  1437. return res;
  1438. }
  1439. else
  1440. #endif //NOLAYERS
  1441. return PostMessage(GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, m_SocketData.hSocket, lEvent%0xFFFF);
  1442. }
  1443. SOCKET CAsyncSocketEx::GetSocketHandle()
  1444. {
  1445. return m_SocketData.hSocket;
  1446. }
  1447. HWND CAsyncSocketEx::GetHelperWindowHandle()
  1448. {
  1449. if (!m_pLocalAsyncSocketExThreadData)
  1450. return 0;
  1451. if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  1452. return 0;
  1453. return m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd();
  1454. }
  1455. #ifndef NOLAYERS
  1456. BOOL CAsyncSocketEx::AddLayer(CAsyncSocketExLayer *pLayer)
  1457. {
  1458. ASSERT(pLayer);
  1459. if (m_pFirstLayer)
  1460. {
  1461. ASSERT(m_pLastLayer);
  1462. m_pLastLayer=m_pLastLayer->AddLayer(pLayer, this);
  1463. return m_pLastLayer?TRUE:FALSE;
  1464. }
  1465. else
  1466. {
  1467. ASSERT(!m_pLastLayer);
  1468. pLayer->Init(0, this);
  1469. m_pFirstLayer=pLayer;
  1470. m_pLastLayer=m_pFirstLayer;
  1471. if (m_SocketData.hSocket != INVALID_SOCKET)
  1472. if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1473. return FALSE;
  1474. }
  1475. return TRUE;
  1476. }
  1477. void CAsyncSocketEx::RemoveAllLayers()
  1478. {
  1479. for (std::list<t_callbackMsg>::iterator iter = m_pendingCallbacks.begin(); iter != m_pendingCallbacks.end(); iter++)
  1480. delete [] iter->str;
  1481. m_pendingCallbacks.clear();
  1482. m_pFirstLayer = 0;
  1483. m_pLastLayer = 0;
  1484. if (!m_pLocalAsyncSocketExThreadData)
  1485. return;
  1486. if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  1487. return;
  1488. m_pLocalAsyncSocketExThreadData->m_pHelperWindow->RemoveLayers(this);
  1489. }
  1490. int CAsyncSocketEx::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
  1491. {
  1492. for (std::list<t_callbackMsg>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++)
  1493. {
  1494. delete [] iter->str;
  1495. }
  1496. return 0;
  1497. }
  1498. BOOL CAsyncSocketEx::IsLayerAttached() const
  1499. {
  1500. return m_pFirstLayer ? TRUE : FALSE;
  1501. }
  1502. #endif //NOLAYERS
  1503. BOOL CAsyncSocketEx::GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel /*=SOL_SOCKET*/)
  1504. {
  1505. return (SOCKET_ERROR != getsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen));
  1506. }
  1507. BOOL CAsyncSocketEx::SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel /*=SOL_SOCKET*/)
  1508. {
  1509. return (SOCKET_ERROR != setsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, nOptionLen));
  1510. }
  1511. #ifndef NOSOCKETSTATES
  1512. int CAsyncSocketEx::GetState() const
  1513. {
  1514. return m_nState;
  1515. }
  1516. void CAsyncSocketEx::SetState(int nState)
  1517. {
  1518. m_nState = nState;
  1519. }
  1520. const TCHAR * CAsyncSocketEx::GetStateDesc(int nState)
  1521. {
  1522. switch (nState)
  1523. {
  1524. case notsock:
  1525. return _T("none");
  1526. case unconnected:
  1527. return _T("unconnected");
  1528. case connecting:
  1529. return _T("connecting");
  1530. case listening:
  1531. return _T("listening");
  1532. case connected:
  1533. return _T("connected");
  1534. case closed:
  1535. return _T("closed");
  1536. case aborted:
  1537. return _T("aborted");
  1538. case attached:
  1539. return _T("attached");
  1540. default:
  1541. return _T("unknown");
  1542. }
  1543. }
  1544. bool CAsyncSocketEx::LogStateChange(int nState1, int nState2)
  1545. {
  1546. return (nState2 != notsock) || (nState1 != unconnected);
  1547. }
  1548. #endif //NOSOCKETSTATES
  1549. int CAsyncSocketEx::GetFamily() const
  1550. {
  1551. return m_SocketData.nFamily;
  1552. }
  1553. bool CAsyncSocketEx::SetFamily(int nFamily)
  1554. {
  1555. if (m_SocketData.nFamily != AF_UNSPEC)
  1556. return false;
  1557. m_SocketData.nFamily = nFamily;
  1558. return true;
  1559. }
  1560. bool CAsyncSocketEx::TryNextProtocol()
  1561. {
  1562. DetachHandle(m_SocketData.hSocket);
  1563. closesocket(m_SocketData.hSocket);
  1564. m_SocketData.hSocket = INVALID_SOCKET;
  1565. BOOL ret = FALSE;
  1566. for (; m_SocketData.nextAddr; m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next)
  1567. {
  1568. m_SocketData.hSocket = socket(m_SocketData.nextAddr->ai_family, m_SocketData.nextAddr->ai_socktype, m_SocketData.nextAddr->ai_protocol);
  1569. if (m_SocketData.hSocket == INVALID_SOCKET)
  1570. continue;
  1571. AttachHandle(m_SocketData.hSocket);
  1572. m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1573. if (!AsyncSelect(m_lEvent))
  1574. {
  1575. DetachHandle(m_SocketData.hSocket);
  1576. closesocket(m_SocketData.hSocket);
  1577. m_SocketData.hSocket = INVALID_SOCKET;
  1578. continue;
  1579. }
  1580. #ifndef NOLAYERS
  1581. if (m_pFirstLayer)
  1582. {
  1583. if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1584. {
  1585. DetachHandle(m_SocketData.hSocket);
  1586. closesocket(m_SocketData.hSocket);
  1587. m_SocketData.hSocket = INVALID_SOCKET;
  1588. continue;
  1589. }
  1590. }
  1591. #endif //NOLAYERS
  1592. if (!Bind(m_nSocketPort, m_lpszSocketAddress))
  1593. {
  1594. DetachHandle(m_SocketData.hSocket);
  1595. closesocket(m_SocketData.hSocket);
  1596. m_SocketData.hSocket = INVALID_SOCKET;
  1597. continue;
  1598. }
  1599. ret = CAsyncSocketEx::Connect(m_SocketData.nextAddr->ai_addr, m_SocketData.nextAddr->ai_addrlen);
  1600. if (!ret && GetLastError() != WSAEWOULDBLOCK)
  1601. {
  1602. DetachHandle(m_SocketData.hSocket);
  1603. closesocket(m_SocketData.hSocket);
  1604. m_SocketData.hSocket = INVALID_SOCKET;
  1605. continue;
  1606. }
  1607. ret = true;
  1608. break;
  1609. }
  1610. if (m_SocketData.nextAddr)
  1611. m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next;
  1612. if (!m_SocketData.nextAddr)
  1613. {
  1614. freeaddrinfo(m_SocketData.addrInfo);
  1615. m_SocketData.nextAddr = 0;
  1616. m_SocketData.addrInfo = 0;
  1617. }
  1618. if (m_SocketData.hSocket == INVALID_SOCKET || !ret)
  1619. return FALSE;
  1620. else
  1621. return TRUE;
  1622. }
  1623. #ifndef NOLAYERS
  1624. void CAsyncSocketEx::AddCallbackNotification(const t_callbackMsg& msg)
  1625. {
  1626. m_pendingCallbacks.push_back(msg);
  1627. if(m_pendingCallbacks.size() == 1 && m_SocketData.nSocketIndex != -1)
  1628. PostMessage(GetHelperWindowHandle(), WM_USER + 2, (WPARAM)m_SocketData.nSocketIndex, 0);
  1629. }
  1630. #endif //NOLAYERS
  1631. void CAsyncSocketEx::ResendCloseNotify()
  1632. {
  1633. for (std::list<CAsyncSocketEx*>::iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); iter++)
  1634. {
  1635. if (*iter == this)
  1636. return;
  1637. }
  1638. m_pLocalAsyncSocketExThreadData->layerCloseNotify.push_back(this);
  1639. if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.size() == 1)
  1640. {
  1641. SetTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1, 10, 0);
  1642. }
  1643. }