AsyncSocketEx.cpp 52 KB

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