AsyncSocketEx.cpp 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894
  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 CAsyncSocketExHelperWindow::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_pAsyncGetHostByNameBuffer = NULL;
  702. m_hAsyncGetHostByNameHandle = NULL;
  703. m_nSocketPort = 0;
  704. m_lpszSocketAddress = 0;
  705. m_SocketData.addrInfo = 0;
  706. m_SocketData.nextAddr = 0;
  707. }
  708. CAsyncSocketEx::~CAsyncSocketEx()
  709. {
  710. Close();
  711. FreeAsyncSocketExInstance();
  712. }
  713. 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*/)
  714. {
  715. ASSERT(GetSocketHandle() == INVALID_SOCKET);
  716. //Close the socket, although this should not happen
  717. if (GetSocketHandle() != INVALID_SOCKET)
  718. {
  719. WSASetLastError(WSAEALREADY);
  720. return FALSE;
  721. }
  722. BOOL res = InitAsyncSocketExInstance();
  723. ASSERT(res);
  724. if (!res)
  725. {
  726. WSASetLastError(WSANOTINITIALISED);
  727. return FALSE;
  728. }
  729. m_SocketData.nFamily = nFamily;
  730. #ifndef NOLAYERS
  731. if (m_pFirstLayer)
  732. {
  733. BOOL res = m_pFirstLayer->Create(nSocketPort, nSocketType, lEvent, lpszSocketAddress, nFamily);
  734. #ifndef NOSOCKETSTATES
  735. if (res)
  736. SetState(unconnected);
  737. #endif //NOSOCKETSTATES
  738. return res;
  739. }
  740. else
  741. #endif //NOLAYERS
  742. {
  743. if (m_SocketData.nFamily == AF_UNSPEC)
  744. {
  745. #ifndef NOSOCKETSTATES
  746. SetState(unconnected);
  747. #endif //NOSOCKETSTATES
  748. m_lEvent = lEvent;
  749. m_nSocketPort = nSocketPort;
  750. delete [] m_lpszSocketAddress;
  751. if (lpszSocketAddress && *lpszSocketAddress)
  752. {
  753. m_lpszSocketAddress = new TCHAR[_tcslen(lpszSocketAddress) + 1];
  754. _tcscpy(m_lpszSocketAddress, lpszSocketAddress);
  755. }
  756. else
  757. m_lpszSocketAddress = 0;
  758. return TRUE;
  759. }
  760. else
  761. {
  762. SOCKET hSocket = socket(m_SocketData.nFamily, nSocketType, 0);
  763. if (hSocket == INVALID_SOCKET)
  764. return FALSE;
  765. m_SocketData.hSocket = hSocket;
  766. AttachHandle(hSocket);
  767. #ifndef NOLAYERS
  768. if (m_pFirstLayer)
  769. {
  770. m_lEvent = lEvent;
  771. if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE) )
  772. {
  773. Close();
  774. return FALSE;
  775. }
  776. }
  777. else
  778. #endif //NOLAYERS
  779. {
  780. if (!AsyncSelect(lEvent))
  781. {
  782. Close();
  783. return FALSE;
  784. }
  785. }
  786. if (!Bind(nSocketPort, lpszSocketAddress))
  787. {
  788. Close();
  789. return FALSE;
  790. }
  791. #ifndef NOSOCKETSTATES
  792. SetState(unconnected);
  793. #endif //NOSOCKETSTATES
  794. return TRUE;
  795. }
  796. }
  797. }
  798. void CAsyncSocketEx::OnReceive(int nErrorCode)
  799. {
  800. }
  801. void CAsyncSocketEx::OnSend(int nErrorCode)
  802. {
  803. }
  804. void CAsyncSocketEx::OnConnect(int nErrorCode)
  805. {
  806. }
  807. void CAsyncSocketEx::OnAccept(int nErrorCode)
  808. {
  809. }
  810. void CAsyncSocketEx::OnClose(int nErrorCode)
  811. {
  812. }
  813. BOOL CAsyncSocketEx::Bind(UINT nSocketPort, LPCTSTR lpszSocketAddress)
  814. {
  815. delete [] m_lpszSocketAddress;
  816. if (lpszSocketAddress && *lpszSocketAddress)
  817. {
  818. m_lpszSocketAddress = new TCHAR[_tcslen(lpszSocketAddress) + 1];
  819. _tcscpy(m_lpszSocketAddress, lpszSocketAddress);
  820. }
  821. else
  822. m_lpszSocketAddress = 0;
  823. m_nSocketPort = nSocketPort;
  824. if (m_SocketData.nFamily == AF_UNSPEC)
  825. return TRUE;
  826. USES_CONVERSION;
  827. LPSTR lpszAscii = (lpszSocketAddress && *lpszSocketAddress) ? T2A((LPTSTR)lpszSocketAddress) : 0;
  828. if ((m_SocketData.nFamily == AF_INET6 || m_SocketData.nFamily == AF_INET) && lpszAscii)
  829. {
  830. if (!p_getaddrinfo)
  831. {
  832. if (m_SocketData.nFamily != AF_INET)
  833. {
  834. WSASetLastError(WSAEPROTONOSUPPORT);
  835. return FALSE;
  836. }
  837. else
  838. {
  839. unsigned long ip = inet_addr(lpszAscii);
  840. if (!ip)
  841. {
  842. WSASetLastError(WSAEINVAL);
  843. return FALSE;
  844. }
  845. SOCKADDR_IN sockAddr;
  846. memset(&sockAddr, 0, sizeof(sockAddr));
  847. sockAddr.sin_family = m_SocketData.nFamily;
  848. sockAddr.sin_addr.s_addr = ip;
  849. sockAddr.sin_port = htons((u_short)nSocketPort);
  850. return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  851. }
  852. }
  853. addrinfo hints, *res0, *res;
  854. int error;
  855. char port[10];
  856. BOOL ret = FALSE;
  857. memset(&hints, 0, sizeof(addrinfo));
  858. hints.ai_family = m_SocketData.nFamily;
  859. hints.ai_socktype = SOCK_STREAM;
  860. _snprintf(port, 9, "%lu", nSocketPort);
  861. error = p_getaddrinfo(lpszAscii, port, &hints, &res0);
  862. if (error)
  863. return FALSE;
  864. for (res = res0; res; res = res->ai_next)
  865. if (Bind(res->ai_addr, res->ai_addrlen))
  866. {
  867. ret = TRUE;
  868. break;
  869. }
  870. else
  871. continue ;
  872. p_freeaddrinfo(res0);
  873. return ret ;
  874. }
  875. else if (!lpszAscii && m_SocketData.nFamily == AF_INET6)
  876. {
  877. SOCKADDR_IN6 sockAddr6;
  878. memset(&sockAddr6, 0, sizeof(sockAddr6));
  879. sockAddr6.sin6_family = AF_INET6 ;
  880. sockAddr6.sin6_addr = in6addr_any ;
  881. sockAddr6.sin6_port = htons((u_short)nSocketPort);
  882. return Bind((SOCKADDR*)&sockAddr6, sizeof(sockAddr6));
  883. }
  884. else if (!lpszAscii && m_SocketData.nFamily == AF_INET)
  885. {
  886. SOCKADDR_IN sockAddr;
  887. memset(&sockAddr, 0, sizeof(sockAddr));
  888. sockAddr.sin_family = AF_INET ;
  889. sockAddr.sin_addr.s_addr = INADDR_ANY ;
  890. sockAddr.sin_port = htons((u_short)nSocketPort);
  891. return Bind((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  892. }
  893. else
  894. return FALSE ;
  895. }
  896. BOOL CAsyncSocketEx::Bind(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  897. {
  898. if (!bind(m_SocketData.hSocket, lpSockAddr, nSockAddrLen))
  899. return TRUE;
  900. else
  901. return FALSE;
  902. }
  903. void CAsyncSocketEx::AttachHandle(SOCKET hSocket)
  904. {
  905. ASSERT(m_pLocalAsyncSocketExThreadData);
  906. VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->AddSocket(this, m_SocketData.nSocketIndex));
  907. #ifndef NOSOCKETSTATES
  908. SetState(attached);
  909. #endif //NOSOCKETSTATES
  910. }
  911. void CAsyncSocketEx::DetachHandle(SOCKET hSocket)
  912. {
  913. ASSERT(m_pLocalAsyncSocketExThreadData);
  914. if (!m_pLocalAsyncSocketExThreadData)
  915. return;
  916. ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
  917. if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  918. return;
  919. VERIFY(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->RemoveSocket(this, m_SocketData.nSocketIndex));
  920. #ifndef NOSOCKETSTATES
  921. SetState(notsock);
  922. #endif //NOSOCKETSTATES
  923. }
  924. void CAsyncSocketEx::Close()
  925. {
  926. #ifndef NOSOCKETSTATES
  927. m_nPendingEvents = 0;
  928. #endif //NOSOCKETSTATES
  929. #ifndef NOLAYERS
  930. if (m_pFirstLayer)
  931. m_pFirstLayer->Close();
  932. #endif //NOLAYERS
  933. if (m_SocketData.hSocket != INVALID_SOCKET)
  934. {
  935. VERIFY((closesocket(m_SocketData.hSocket) != SOCKET_ERROR));
  936. DetachHandle(m_SocketData.hSocket);
  937. m_SocketData.hSocket = INVALID_SOCKET;
  938. }
  939. if (m_SocketData.addrInfo)
  940. {
  941. p_freeaddrinfo(m_SocketData.addrInfo);
  942. m_SocketData.addrInfo = 0;
  943. m_SocketData.nextAddr = 0;
  944. }
  945. m_SocketData.nFamily = AF_UNSPEC;
  946. delete [] m_lpszSocketAddress;
  947. m_lpszSocketAddress = 0;
  948. m_nSocketPort = 0;
  949. #ifndef NOLAYERS
  950. RemoveAllLayers();
  951. #endif //NOLAYERS
  952. delete [] m_pAsyncGetHostByNameBuffer;
  953. m_pAsyncGetHostByNameBuffer = NULL;
  954. if (m_hAsyncGetHostByNameHandle)
  955. WSACancelAsyncRequest(m_hAsyncGetHostByNameHandle);
  956. m_hAsyncGetHostByNameHandle = NULL;
  957. m_SocketData.onCloseCalled = false;
  958. }
  959. BOOL CAsyncSocketEx::InitAsyncSocketExInstance()
  960. {
  961. //Check if already initialized
  962. if (m_pLocalAsyncSocketExThreadData)
  963. return TRUE;
  964. DWORD id=GetCurrentThreadId();
  965. m_sGlobalCriticalSection.Lock();
  966. //Get thread specific data
  967. if (m_spAsyncSocketExThreadDataList)
  968. {
  969. t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
  970. while (pList)
  971. {
  972. ASSERT(pList->pThreadData);
  973. ASSERT(pList->pThreadData->nInstanceCount>0);
  974. if (pList->pThreadData->nThreadId==id)
  975. {
  976. m_pLocalAsyncSocketExThreadData=pList->pThreadData;
  977. m_pLocalAsyncSocketExThreadData->nInstanceCount++;
  978. break;
  979. }
  980. pList=pList->pNext;
  981. }
  982. //Current thread yet has no sockets
  983. if (!pList)
  984. {
  985. //Initialize data for current thread
  986. pList=new t_AsyncSocketExThreadDataList;
  987. pList->pNext=m_spAsyncSocketExThreadDataList;
  988. m_spAsyncSocketExThreadDataList=pList;
  989. m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
  990. m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
  991. m_pLocalAsyncSocketExThreadData->nThreadId=id;
  992. m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow(m_pLocalAsyncSocketExThreadData);
  993. m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
  994. }
  995. }
  996. else
  997. { //No thread has instances of CAsyncSocketEx; Initialize data
  998. m_spAsyncSocketExThreadDataList=new t_AsyncSocketExThreadDataList;
  999. m_spAsyncSocketExThreadDataList->pNext=0;
  1000. m_pLocalAsyncSocketExThreadData=new t_AsyncSocketExThreadData;
  1001. m_pLocalAsyncSocketExThreadData->nInstanceCount=1;
  1002. m_pLocalAsyncSocketExThreadData->nThreadId=id;
  1003. m_pLocalAsyncSocketExThreadData->m_pHelperWindow=new CAsyncSocketExHelperWindow(m_pLocalAsyncSocketExThreadData);
  1004. m_spAsyncSocketExThreadDataList->pThreadData=m_pLocalAsyncSocketExThreadData;
  1005. m_hDll = LoadLibrary(_T("WS2_32.dll"));
  1006. if (m_hDll)
  1007. {
  1008. p_getaddrinfo = (t_getaddrinfo)GetProcAddress(m_hDll, "getaddrinfo");
  1009. p_freeaddrinfo = (t_freeaddrinfo)GetProcAddress(m_hDll, "freeaddrinfo");
  1010. if (!p_getaddrinfo || !p_freeaddrinfo)
  1011. {
  1012. p_getaddrinfo = 0;
  1013. p_freeaddrinfo = 0;
  1014. FreeLibrary(m_hDll);
  1015. m_hDll = 0;
  1016. }
  1017. }
  1018. }
  1019. m_sGlobalCriticalSection.Unlock();
  1020. return TRUE;
  1021. }
  1022. void CAsyncSocketEx::FreeAsyncSocketExInstance()
  1023. {
  1024. //Check if already freed
  1025. if (!m_pLocalAsyncSocketExThreadData)
  1026. return;
  1027. for (std::list<CAsyncSocketEx*>::iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); iter++)
  1028. {
  1029. if (*iter != this)
  1030. continue;
  1031. m_pLocalAsyncSocketExThreadData->layerCloseNotify.erase(iter);
  1032. if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.empty())
  1033. KillTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1);
  1034. break;
  1035. }
  1036. DWORD id=m_pLocalAsyncSocketExThreadData->nThreadId;
  1037. m_sGlobalCriticalSection.Lock();
  1038. ASSERT(m_spAsyncSocketExThreadDataList);
  1039. t_AsyncSocketExThreadDataList *pList=m_spAsyncSocketExThreadDataList;
  1040. t_AsyncSocketExThreadDataList *pPrev=0;
  1041. //Serach for data for current thread and decrease instance count
  1042. while (pList)
  1043. {
  1044. ASSERT(pList->pThreadData);
  1045. ASSERT(pList->pThreadData->nInstanceCount>0);
  1046. if (pList->pThreadData->nThreadId==id)
  1047. {
  1048. ASSERT(m_pLocalAsyncSocketExThreadData==pList->pThreadData);
  1049. m_pLocalAsyncSocketExThreadData->nInstanceCount--;
  1050. //Freeing last instance?
  1051. //If so, destroy helper window
  1052. if (!m_pLocalAsyncSocketExThreadData->nInstanceCount)
  1053. {
  1054. delete m_pLocalAsyncSocketExThreadData->m_pHelperWindow;
  1055. delete m_pLocalAsyncSocketExThreadData;
  1056. if (pPrev)
  1057. pPrev->pNext=pList->pNext;
  1058. else
  1059. m_spAsyncSocketExThreadDataList=pList->pNext;
  1060. delete pList;
  1061. // Last thread closed, free dll
  1062. if (!m_spAsyncSocketExThreadDataList)
  1063. {
  1064. if (m_hDll)
  1065. {
  1066. p_getaddrinfo = 0;
  1067. p_freeaddrinfo = 0;
  1068. FreeLibrary(m_hDll);
  1069. m_hDll = 0;
  1070. }
  1071. }
  1072. break;
  1073. }
  1074. break;
  1075. }
  1076. pPrev=pList;
  1077. pList=pList->pNext;
  1078. ASSERT(pList);
  1079. }
  1080. m_sGlobalCriticalSection.Unlock();
  1081. }
  1082. int CAsyncSocketEx::Receive(void* lpBuf, int nBufLen, int nFlags /*=0*/)
  1083. {
  1084. #ifndef NOLAYERS
  1085. if (m_pFirstLayer)
  1086. return m_pFirstLayer->Receive(lpBuf, nBufLen, nFlags);
  1087. else
  1088. #endif //NOLAYERS
  1089. return recv(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  1090. }
  1091. int CAsyncSocketEx::Send(const void* lpBuf, int nBufLen, int nFlags /*=0*/)
  1092. {
  1093. #ifndef NOLAYERS
  1094. if (m_pFirstLayer)
  1095. return m_pFirstLayer->Send(lpBuf, nBufLen, nFlags);
  1096. else
  1097. #endif //NOLAYERS
  1098. return send(m_SocketData.hSocket, (LPSTR)lpBuf, nBufLen, nFlags);
  1099. }
  1100. BOOL CAsyncSocketEx::Connect(LPCTSTR lpszHostAddress, UINT nHostPort)
  1101. {
  1102. #ifndef NOLAYERS
  1103. if (m_pFirstLayer)
  1104. {
  1105. BOOL res = m_pFirstLayer->Connect(lpszHostAddress, nHostPort);
  1106. #ifndef NOSOCKETSTATES
  1107. if (res || GetLastError()==WSAEWOULDBLOCK)
  1108. SetState(connecting);
  1109. #endif //NOSOCKETSTATES
  1110. return res;
  1111. } else
  1112. #endif //NOLAYERS
  1113. if (m_SocketData.nFamily == AF_INET)
  1114. {
  1115. USES_CONVERSION;
  1116. ASSERT(lpszHostAddress != NULL);
  1117. SOCKADDR_IN sockAddr;
  1118. memset(&sockAddr,0,sizeof(sockAddr));
  1119. LPSTR lpszAscii = T2A((LPTSTR)lpszHostAddress);
  1120. sockAddr.sin_family = AF_INET;
  1121. sockAddr.sin_addr.s_addr = inet_addr(lpszAscii);
  1122. if (sockAddr.sin_addr.s_addr == INADDR_NONE)
  1123. {
  1124. if (m_pAsyncGetHostByNameBuffer)
  1125. delete [] m_pAsyncGetHostByNameBuffer;
  1126. m_pAsyncGetHostByNameBuffer=new char[MAXGETHOSTSTRUCT];
  1127. m_nAsyncGetHostByNamePort=nHostPort;
  1128. m_hAsyncGetHostByNameHandle=WSAAsyncGetHostByName(GetHelperWindowHandle(), WM_USER+1, lpszAscii, m_pAsyncGetHostByNameBuffer, MAXGETHOSTSTRUCT);
  1129. if (!m_hAsyncGetHostByNameHandle)
  1130. return FALSE;
  1131. WSASetLastError(WSAEWOULDBLOCK);
  1132. #ifndef NOSOCKETSTATES
  1133. SetState(connecting);
  1134. #endif //NOSOCKETSTATES
  1135. return FALSE;
  1136. }
  1137. sockAddr.sin_port = htons((u_short)nHostPort);
  1138. return CAsyncSocketEx::Connect((SOCKADDR*)&sockAddr, sizeof(sockAddr));
  1139. }
  1140. else
  1141. {
  1142. if (!p_getaddrinfo)
  1143. {
  1144. WSASetLastError(WSAEPROTONOSUPPORT);
  1145. return FALSE;
  1146. }
  1147. USES_CONVERSION;
  1148. ASSERT( lpszHostAddress != NULL );
  1149. if (m_SocketData.addrInfo)
  1150. {
  1151. p_freeaddrinfo(m_SocketData.addrInfo);
  1152. m_SocketData.addrInfo = 0;
  1153. m_SocketData.nextAddr = 0;
  1154. }
  1155. addrinfo hints;
  1156. int error;
  1157. BOOL ret;
  1158. char port[10];
  1159. memset(&hints, 0, sizeof(addrinfo));
  1160. hints.ai_family = m_SocketData.nFamily;
  1161. hints.ai_socktype = SOCK_STREAM;
  1162. _snprintf(port, 9, "%lu", nHostPort);
  1163. error = p_getaddrinfo(T2CA(lpszHostAddress), port, &hints, &m_SocketData.addrInfo);
  1164. if (error)
  1165. return FALSE;
  1166. for (m_SocketData.nextAddr = m_SocketData.addrInfo; m_SocketData.nextAddr; m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next)
  1167. {
  1168. bool newSocket = false;
  1169. if (m_SocketData.nFamily == AF_UNSPEC)
  1170. {
  1171. newSocket = true;
  1172. m_SocketData.hSocket = socket(m_SocketData.nextAddr->ai_family, m_SocketData.nextAddr->ai_socktype, m_SocketData.nextAddr->ai_protocol);
  1173. if (m_SocketData.hSocket == INVALID_SOCKET)
  1174. continue;
  1175. m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1176. AttachHandle(m_SocketData.hSocket);
  1177. if (!AsyncSelect(m_lEvent))
  1178. {
  1179. if (newSocket)
  1180. {
  1181. DetachHandle(m_SocketData.hSocket);
  1182. closesocket(m_SocketData.hSocket);
  1183. m_SocketData.hSocket = INVALID_SOCKET;
  1184. }
  1185. continue;
  1186. }
  1187. }
  1188. else if (m_SocketData.hSocket == INVALID_SOCKET)
  1189. continue;
  1190. #ifndef NOLAYERS
  1191. if (m_pFirstLayer)
  1192. {
  1193. if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1194. {
  1195. if (newSocket)
  1196. {
  1197. m_SocketData.nFamily = AF_UNSPEC;
  1198. DetachHandle(m_SocketData.hSocket);
  1199. closesocket(m_SocketData.hSocket);
  1200. m_SocketData.hSocket = INVALID_SOCKET;
  1201. }
  1202. continue;
  1203. }
  1204. }
  1205. #endif //NOLAYERS
  1206. if (newSocket)
  1207. {
  1208. m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1209. if (!Bind(m_nSocketPort, m_lpszSocketAddress))
  1210. {
  1211. m_SocketData.nFamily = AF_UNSPEC;
  1212. DetachHandle(m_SocketData.hSocket);
  1213. closesocket(m_SocketData.hSocket);
  1214. m_SocketData.hSocket = INVALID_SOCKET;
  1215. continue;
  1216. }
  1217. }
  1218. if (!(ret = CAsyncSocketEx::Connect(m_SocketData.nextAddr->ai_addr, m_SocketData.nextAddr->ai_addrlen)) && GetLastError() != WSAEWOULDBLOCK)
  1219. {
  1220. if (newSocket)
  1221. {
  1222. m_SocketData.nFamily = AF_UNSPEC;
  1223. DetachHandle(m_SocketData.hSocket);
  1224. closesocket(m_SocketData.hSocket);
  1225. m_SocketData.hSocket = INVALID_SOCKET;
  1226. }
  1227. continue;
  1228. }
  1229. break;
  1230. }
  1231. if (m_SocketData.nextAddr)
  1232. m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next;
  1233. if (!m_SocketData.nextAddr)
  1234. {
  1235. p_freeaddrinfo(m_SocketData.addrInfo);
  1236. m_SocketData.nextAddr = 0;
  1237. m_SocketData.addrInfo = 0;
  1238. }
  1239. if (m_SocketData.hSocket == INVALID_SOCKET || !ret)
  1240. return FALSE;
  1241. else
  1242. return TRUE;
  1243. }
  1244. }
  1245. BOOL CAsyncSocketEx::Connect(const SOCKADDR* lpSockAddr, int nSockAddrLen)
  1246. {
  1247. BOOL res;
  1248. #ifndef NOLAYERS
  1249. if (m_pFirstLayer)
  1250. res = SOCKET_ERROR!=m_pFirstLayer->Connect(lpSockAddr, nSockAddrLen);
  1251. else
  1252. #endif //NOLAYERS
  1253. res = SOCKET_ERROR!=connect(m_SocketData.hSocket, lpSockAddr, nSockAddrLen);
  1254. #ifndef NOSOCKETSTATES
  1255. if (res || GetLastError()==WSAEWOULDBLOCK)
  1256. SetState(connecting);
  1257. #endif //NOSOCKETSTATES
  1258. return res;
  1259. }
  1260. #ifdef _AFX
  1261. BOOL CAsyncSocketEx::GetPeerName( CString& rPeerAddress, UINT& rPeerPort )
  1262. {
  1263. #ifndef NOLAYERS
  1264. if (m_pFirstLayer)
  1265. return m_pFirstLayer->GetPeerName(rPeerAddress, rPeerPort);
  1266. #endif NOLAYERS
  1267. SOCKADDR* sockAddr;
  1268. int nSockAddrLen;
  1269. if (m_SocketData.nFamily == AF_INET6)
  1270. {
  1271. sockAddr = (SOCKADDR*)new SOCKADDR_IN6;
  1272. nSockAddrLen = sizeof(SOCKADDR_IN6);
  1273. }
  1274. else if (m_SocketData.nFamily == AF_INET)
  1275. {
  1276. sockAddr = (SOCKADDR*)new SOCKADDR_IN;
  1277. nSockAddrLen = sizeof(SOCKADDR_IN);
  1278. }
  1279. memset(sockAddr, 0, nSockAddrLen);
  1280. BOOL bResult = GetPeerName(sockAddr, &nSockAddrLen);
  1281. if (bResult)
  1282. {
  1283. if (m_SocketData.nFamily == AF_INET6)
  1284. {
  1285. rPeerPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);
  1286. LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);
  1287. rPeerAddress = buf;
  1288. delete [] buf;
  1289. }
  1290. else if (m_SocketData.nFamily == AF_INET)
  1291. {
  1292. rPeerPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);
  1293. rPeerAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);
  1294. }
  1295. else
  1296. {
  1297. delete sockAddr;
  1298. return FALSE;
  1299. }
  1300. }
  1301. delete sockAddr;
  1302. return bResult;
  1303. }
  1304. #endif //_AFX
  1305. BOOL CAsyncSocketEx::GetPeerName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1306. {
  1307. #ifndef NOLAYERS
  1308. if (m_pFirstLayer)
  1309. return m_pFirstLayer->GetPeerName(lpSockAddr, lpSockAddrLen);
  1310. #endif //NOLAYERS
  1311. if (!getpeername(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen))
  1312. return TRUE;
  1313. else
  1314. return FALSE;
  1315. }
  1316. #ifdef _AFX
  1317. BOOL CAsyncSocketEx::GetSockName(CString& rSocketAddress, UINT& rSocketPort)
  1318. {
  1319. SOCKADDR* sockAddr;
  1320. int nSockAddrLen;
  1321. if (m_SocketData.nFamily == AF_INET6)
  1322. {
  1323. sockAddr = (SOCKADDR*)new SOCKADDR_IN6;
  1324. nSockAddrLen = sizeof(SOCKADDR_IN6);
  1325. }
  1326. else if (m_SocketData.nFamily == AF_INET)
  1327. {
  1328. sockAddr = (SOCKADDR*)new SOCKADDR_IN;
  1329. nSockAddrLen = sizeof(SOCKADDR_IN);
  1330. }
  1331. memset(sockAddr, 0, nSockAddrLen);
  1332. BOOL bResult = GetSockName(sockAddr, &nSockAddrLen);
  1333. if (bResult)
  1334. {
  1335. if (m_SocketData.nFamily == AF_INET6)
  1336. {
  1337. rSocketPort = ntohs(((SOCKADDR_IN6*)sockAddr)->sin6_port);
  1338. LPTSTR buf = Inet6AddrToString(((SOCKADDR_IN6*)sockAddr)->sin6_addr);
  1339. rSocketAddress = buf;
  1340. delete [] buf;
  1341. }
  1342. else if (m_SocketData.nFamily == AF_INET)
  1343. {
  1344. rSocketPort = ntohs(((SOCKADDR_IN*)sockAddr)->sin_port);
  1345. rSocketAddress = inet_ntoa(((SOCKADDR_IN*)sockAddr)->sin_addr);
  1346. }
  1347. else
  1348. {
  1349. delete sockAddr;
  1350. return FALSE;
  1351. }
  1352. }
  1353. delete sockAddr;
  1354. return bResult;
  1355. }
  1356. #endif //_AFX
  1357. BOOL CAsyncSocketEx::GetSockName( SOCKADDR* lpSockAddr, int* lpSockAddrLen )
  1358. {
  1359. if ( !getsockname(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen) )
  1360. return TRUE;
  1361. else
  1362. return FALSE;
  1363. }
  1364. BOOL CAsyncSocketEx::ShutDown(int nHow /*=sends*/)
  1365. {
  1366. #ifndef NOLAYERS
  1367. if (m_pFirstLayer)
  1368. {
  1369. return m_pFirstLayer->ShutDown();
  1370. }
  1371. else
  1372. #endif //NOLAYERS
  1373. {
  1374. if (!shutdown(m_SocketData.hSocket, nHow))
  1375. return TRUE;
  1376. else
  1377. return FALSE;
  1378. }
  1379. }
  1380. SOCKET CAsyncSocketEx::Detach()
  1381. {
  1382. SOCKET socket = m_SocketData.hSocket;
  1383. DetachHandle(socket);
  1384. m_SocketData.hSocket = INVALID_SOCKET;
  1385. m_SocketData.nFamily = AF_UNSPEC;
  1386. return socket;
  1387. }
  1388. BOOL CAsyncSocketEx::Attach(SOCKET hSocket, long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/)
  1389. {
  1390. if (hSocket==INVALID_SOCKET || !hSocket)
  1391. return FALSE;
  1392. VERIFY(InitAsyncSocketExInstance());
  1393. m_SocketData.hSocket=hSocket;
  1394. AttachHandle(hSocket);
  1395. #ifndef NOLAYERS
  1396. if (m_pFirstLayer)
  1397. {
  1398. m_lEvent = lEvent;
  1399. return !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE);
  1400. }
  1401. else
  1402. #endif //NOLAYERS
  1403. {
  1404. return AsyncSelect(lEvent);
  1405. }
  1406. }
  1407. BOOL CAsyncSocketEx::AsyncSelect( long lEvent /*= FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE*/ )
  1408. {
  1409. ASSERT(m_pLocalAsyncSocketExThreadData);
  1410. m_lEvent = lEvent;
  1411. #ifndef NOLAYERS
  1412. if (m_pFirstLayer)
  1413. return TRUE;
  1414. else
  1415. #endif //NOLAYERS
  1416. {
  1417. if (m_SocketData.hSocket == INVALID_SOCKET && m_SocketData.nFamily == AF_UNSPEC)
  1418. return true;
  1419. if ( !WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, lEvent) )
  1420. return TRUE;
  1421. else
  1422. return FALSE;
  1423. }
  1424. return TRUE;
  1425. }
  1426. BOOL CAsyncSocketEx::Listen( int nConnectionBacklog /*=5*/ )
  1427. {
  1428. #ifndef NOLAYERS
  1429. if (m_pFirstLayer)
  1430. return m_pFirstLayer->Listen(nConnectionBacklog);
  1431. #endif //NOLAYERS
  1432. if (!listen(m_SocketData.hSocket, nConnectionBacklog))
  1433. {
  1434. #ifndef NOSOCKETSTATES
  1435. SetState(listening);
  1436. #endif //NOSOCKETSTATES
  1437. return TRUE;
  1438. }
  1439. else
  1440. return FALSE;
  1441. }
  1442. BOOL CAsyncSocketEx::Accept( CAsyncSocketEx& rConnectedSocket, SOCKADDR* lpSockAddr /*=NULL*/, int* lpSockAddrLen /*=NULL*/ )
  1443. {
  1444. ASSERT(rConnectedSocket.m_SocketData.hSocket == INVALID_SOCKET);
  1445. #ifndef NOLAYERS
  1446. if (m_pFirstLayer)
  1447. {
  1448. return m_pFirstLayer->Accept(rConnectedSocket, lpSockAddr, lpSockAddrLen);
  1449. }
  1450. else
  1451. #endif //NOLAYERS
  1452. {
  1453. SOCKET hTemp = accept(m_SocketData.hSocket, lpSockAddr, lpSockAddrLen);
  1454. if (hTemp == INVALID_SOCKET)
  1455. return FALSE;
  1456. VERIFY(rConnectedSocket.InitAsyncSocketExInstance());
  1457. rConnectedSocket.m_SocketData.hSocket=hTemp;
  1458. rConnectedSocket.AttachHandle(hTemp);
  1459. rConnectedSocket.SetFamily(GetFamily());
  1460. #ifndef NOSOCKETSTATES
  1461. rConnectedSocket.SetState(connected);
  1462. #endif //NOSOCKETSTATES
  1463. }
  1464. return TRUE;
  1465. }
  1466. BOOL CAsyncSocketEx::IOCtl( long lCommand, DWORD* lpArgument )
  1467. {
  1468. return ioctlsocket(m_SocketData.hSocket, lCommand, lpArgument) != SOCKET_ERROR;
  1469. }
  1470. int CAsyncSocketEx::GetLastError()
  1471. {
  1472. return WSAGetLastError();
  1473. }
  1474. BOOL CAsyncSocketEx::TriggerEvent(long lEvent)
  1475. {
  1476. if (m_SocketData.hSocket==INVALID_SOCKET)
  1477. return FALSE;
  1478. ASSERT(m_pLocalAsyncSocketExThreadData);
  1479. ASSERT(m_pLocalAsyncSocketExThreadData->m_pHelperWindow);
  1480. ASSERT(m_SocketData.nSocketIndex!=-1);
  1481. #ifndef NOLAYERS
  1482. if (m_pFirstLayer)
  1483. {
  1484. CAsyncSocketExLayer::t_LayerNotifyMsg *pMsg = new CAsyncSocketExLayer::t_LayerNotifyMsg;
  1485. pMsg->hSocket = m_SocketData.hSocket;
  1486. pMsg->lEvent=lEvent%0xFFFF;
  1487. pMsg->pLayer=0;
  1488. BOOL res=PostMessage(GetHelperWindowHandle(), WM_USER, (WPARAM)m_SocketData.nSocketIndex, (LPARAM)pMsg);
  1489. if (!res)
  1490. delete pMsg;
  1491. return res;
  1492. }
  1493. else
  1494. #endif //NOLAYERS
  1495. return PostMessage(GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, m_SocketData.hSocket, lEvent%0xFFFF);
  1496. }
  1497. SOCKET CAsyncSocketEx::GetSocketHandle()
  1498. {
  1499. return m_SocketData.hSocket;
  1500. }
  1501. HWND CAsyncSocketEx::GetHelperWindowHandle()
  1502. {
  1503. if (!m_pLocalAsyncSocketExThreadData)
  1504. return 0;
  1505. if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  1506. return 0;
  1507. return m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd();
  1508. }
  1509. #ifndef NOLAYERS
  1510. BOOL CAsyncSocketEx::AddLayer(CAsyncSocketExLayer *pLayer)
  1511. {
  1512. ASSERT(pLayer);
  1513. if (m_pFirstLayer)
  1514. {
  1515. ASSERT(m_pLastLayer);
  1516. m_pLastLayer=m_pLastLayer->AddLayer(pLayer, this);
  1517. return m_pLastLayer?TRUE:FALSE;
  1518. }
  1519. else
  1520. {
  1521. ASSERT(!m_pLastLayer);
  1522. pLayer->Init(0, this);
  1523. m_pFirstLayer=pLayer;
  1524. m_pLastLayer=m_pFirstLayer;
  1525. if (m_SocketData.hSocket != INVALID_SOCKET)
  1526. if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1527. return FALSE;
  1528. }
  1529. return TRUE;
  1530. }
  1531. void CAsyncSocketEx::RemoveAllLayers()
  1532. {
  1533. for (std::list<t_callbackMsg>::iterator iter = m_pendingCallbacks.begin(); iter != m_pendingCallbacks.end(); iter++)
  1534. delete [] iter->str;
  1535. m_pendingCallbacks.clear();
  1536. m_pFirstLayer = 0;
  1537. m_pLastLayer = 0;
  1538. if (!m_pLocalAsyncSocketExThreadData)
  1539. return;
  1540. if (!m_pLocalAsyncSocketExThreadData->m_pHelperWindow)
  1541. return;
  1542. m_pLocalAsyncSocketExThreadData->m_pHelperWindow->RemoveLayers(this);
  1543. }
  1544. int CAsyncSocketEx::OnLayerCallback(std::list<t_callbackMsg>& callbacks)
  1545. {
  1546. for (std::list<t_callbackMsg>::iterator iter = callbacks.begin(); iter != callbacks.end(); iter++)
  1547. {
  1548. delete [] iter->str;
  1549. }
  1550. return 0;
  1551. }
  1552. BOOL CAsyncSocketEx::IsLayerAttached() const
  1553. {
  1554. return m_pFirstLayer ? TRUE : FALSE;
  1555. }
  1556. #endif //NOLAYERS
  1557. BOOL CAsyncSocketEx::GetSockOpt(int nOptionName, void* lpOptionValue, int* lpOptionLen, int nLevel /*=SOL_SOCKET*/)
  1558. {
  1559. return (SOCKET_ERROR != getsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, lpOptionLen));
  1560. }
  1561. BOOL CAsyncSocketEx::SetSockOpt(int nOptionName, const void* lpOptionValue, int nOptionLen, int nLevel /*=SOL_SOCKET*/)
  1562. {
  1563. return (SOCKET_ERROR != setsockopt(m_SocketData.hSocket, nLevel, nOptionName, (LPSTR)lpOptionValue, nOptionLen));
  1564. }
  1565. #ifndef NOSOCKETSTATES
  1566. int CAsyncSocketEx::GetState() const
  1567. {
  1568. return m_nState;
  1569. }
  1570. void CAsyncSocketEx::SetState(int nState)
  1571. {
  1572. m_nState = nState;
  1573. }
  1574. #endif //NOSOCKETSTATES
  1575. int CAsyncSocketEx::GetFamily() const
  1576. {
  1577. return m_SocketData.nFamily;
  1578. }
  1579. bool CAsyncSocketEx::SetFamily(int nFamily)
  1580. {
  1581. if (m_SocketData.nFamily != AF_UNSPEC)
  1582. return false;
  1583. m_SocketData.nFamily = nFamily;
  1584. return true;
  1585. }
  1586. bool CAsyncSocketEx::TryNextProtocol()
  1587. {
  1588. DetachHandle(m_SocketData.hSocket);
  1589. closesocket(m_SocketData.hSocket);
  1590. m_SocketData.hSocket = INVALID_SOCKET;
  1591. BOOL ret = FALSE;
  1592. for (; m_SocketData.nextAddr; m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next)
  1593. {
  1594. m_SocketData.hSocket = socket(m_SocketData.nextAddr->ai_family, m_SocketData.nextAddr->ai_socktype, m_SocketData.nextAddr->ai_protocol);
  1595. if (m_SocketData.hSocket == INVALID_SOCKET)
  1596. continue;
  1597. AttachHandle(m_SocketData.hSocket);
  1598. m_SocketData.nFamily = m_SocketData.nextAddr->ai_family;
  1599. if (!AsyncSelect(m_lEvent))
  1600. {
  1601. DetachHandle(m_SocketData.hSocket);
  1602. closesocket(m_SocketData.hSocket);
  1603. m_SocketData.hSocket = INVALID_SOCKET;
  1604. continue;
  1605. }
  1606. #ifndef NOLAYERS
  1607. if (m_pFirstLayer)
  1608. {
  1609. if (WSAAsyncSelect(m_SocketData.hSocket, GetHelperWindowHandle(), m_SocketData.nSocketIndex+WM_SOCKETEX_NOTIFY, FD_READ | FD_WRITE | FD_OOB | FD_ACCEPT | FD_CONNECT | FD_CLOSE))
  1610. {
  1611. DetachHandle(m_SocketData.hSocket);
  1612. closesocket(m_SocketData.hSocket);
  1613. m_SocketData.hSocket = INVALID_SOCKET;
  1614. continue;
  1615. }
  1616. }
  1617. #endif //NOLAYERS
  1618. if (!Bind(m_nSocketPort, m_lpszSocketAddress))
  1619. {
  1620. DetachHandle(m_SocketData.hSocket);
  1621. closesocket(m_SocketData.hSocket);
  1622. m_SocketData.hSocket = INVALID_SOCKET;
  1623. continue;
  1624. }
  1625. ret = CAsyncSocketEx::Connect(m_SocketData.nextAddr->ai_addr, m_SocketData.nextAddr->ai_addrlen);
  1626. if (!ret && GetLastError() != WSAEWOULDBLOCK)
  1627. {
  1628. DetachHandle(m_SocketData.hSocket);
  1629. closesocket(m_SocketData.hSocket);
  1630. m_SocketData.hSocket = INVALID_SOCKET;
  1631. continue;
  1632. }
  1633. ret = true;
  1634. break;
  1635. }
  1636. if (m_SocketData.nextAddr)
  1637. m_SocketData.nextAddr = m_SocketData.nextAddr->ai_next;
  1638. if (!m_SocketData.nextAddr)
  1639. {
  1640. p_freeaddrinfo(m_SocketData.addrInfo);
  1641. m_SocketData.nextAddr = 0;
  1642. m_SocketData.addrInfo = 0;
  1643. }
  1644. if (m_SocketData.hSocket == INVALID_SOCKET || !ret)
  1645. return FALSE;
  1646. else
  1647. return TRUE;
  1648. }
  1649. #ifndef NOLAYERS
  1650. void CAsyncSocketEx::AddCallbackNotification(const t_callbackMsg& msg)
  1651. {
  1652. m_pendingCallbacks.push_back(msg);
  1653. if(m_pendingCallbacks.size() == 1 && m_SocketData.nSocketIndex != -1)
  1654. PostMessage(GetHelperWindowHandle(), WM_USER + 2, (WPARAM)m_SocketData.nSocketIndex, 0);
  1655. }
  1656. #endif //NOLAYERS
  1657. void CAsyncSocketEx::ResendCloseNotify()
  1658. {
  1659. for (std::list<CAsyncSocketEx*>::iterator iter = m_pLocalAsyncSocketExThreadData->layerCloseNotify.begin(); iter != m_pLocalAsyncSocketExThreadData->layerCloseNotify.end(); iter++)
  1660. {
  1661. if (*iter == this)
  1662. return;
  1663. }
  1664. m_pLocalAsyncSocketExThreadData->layerCloseNotify.push_back(this);
  1665. if (m_pLocalAsyncSocketExThreadData->layerCloseNotify.size() == 1)
  1666. {
  1667. SetTimer(m_pLocalAsyncSocketExThreadData->m_pHelperWindow->GetHwnd(), 1, 10, 0);
  1668. }
  1669. }