AsyncSocketEx.cpp 51 KB

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