AsyncSocketEx.cpp 49 KB

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