ConnectThread.cpp 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. /****************************************************************/
  2. /* */
  3. /* CONNECTTHREAD.CPP */
  4. /* */
  5. /* Implementation of the Connect Thread. */
  6. /* Created when a client logs on to the server and processes */
  7. /* 'Send' commando's. */
  8. /* */
  9. /* Programmed by LYFZ van der Meer */
  10. /* http://www.LYFZvandermeer.nl */
  11. /* */
  12. /* Last updated: 15 july 2002 */
  13. /* */
  14. /****************************************************************/
  15. //在ConnectThread.cpp文件中实现连接线程的创建,这个线程用来处理与客户端的连接。
  16. //当一个客户登录到服务器此线程将被创建,并处理"Send"命令。
  17. #include "stdafx.h"
  18. #include "DBServer.h"
  19. #include "theDBServer.h"
  20. #include "DBServerDlg.h"
  21. #include "ConnectThread.h"
  22. #include "MyLock.h"
  23. #ifdef _DEBUG
  24. #define new DEBUG_NEW
  25. #undef THIS_FILE
  26. static char THIS_FILE[] = __FILE__;
  27. #endif
  28. extern CtheDBServer *g_pWndServer;
  29. CStringArray g_connuserarray;
  30. CStringArray g_logintimearray;
  31. extern CConnectThread *g_pThreadPt[200];
  32. extern int g_conncount;
  33. IMPLEMENT_DYNCREATE(CConnectThread, CWinThread)
  34. /********************************************************************/
  35. /* */
  36. /* Function name : CConnectThread::CConnectThread */
  37. /* Description : Constructor */
  38. /* */
  39. /********************************************************************/
  40. CConnectThread::CConnectThread()
  41. {
  42. m_nReceivedBytes = 0;
  43. m_nSentBytes = 0;
  44. m_nTimerID = 0;
  45. m_LastDataTransferTime = CTime::GetCurrentTime();
  46. }
  47. /********************************************************************/
  48. /* */
  49. /* Function name : CConnectThread::~CConnectThread */
  50. /* Description : Destructor */
  51. /* */
  52. /********************************************************************/
  53. CConnectThread::~CConnectThread()
  54. {
  55. }
  56. /********************************************************************/
  57. /* */
  58. /* Function name : InitInstance */
  59. /* Description : Perform tasks that must be completed when the */
  60. /* thread is first created. */
  61. /* */
  62. /********************************************************************/
  63. //初始化线程
  64. int FindArray3(CStringArray *pArray, CString Str)
  65. {
  66. int count=0;
  67. for(int i=0; i<pArray->GetSize (); i++)
  68. {
  69. if(pArray->ElementAt (i)==Str)
  70. count++;
  71. }
  72. return count;
  73. }
  74. extern void GetOneConn(CDatabase **m_pdb, CArray<CDatabase*,CDatabase*>*m_dbarray, CConnectThread *pThread);
  75. extern int FindArray(CStringArray *pArray, CString Str);
  76. void GetConnCount(CStringArray *pArray)
  77. {
  78. g_pWndServer->m_CriticalSection.Lock();
  79. CConnectThread *pThread;
  80. POSITION pos;
  81. pos=g_pWndServer->m_ThreadList.GetHeadPosition();
  82. while(pos)
  83. {
  84. pThread=g_pWndServer->m_ThreadList.GetNext(pos);
  85. if(g_localip==pThread->m_strRemoteHost)continue;
  86. if(::FindArray(pArray, pThread->m_strRemoteHost)==-1)
  87. pArray->Add(pThread->m_strRemoteHost);
  88. }
  89. g_pWndServer->m_CriticalSection.Unlock();
  90. }
  91. BOOL CConnectThread::InitInstance()
  92. {
  93. try
  94. {
  95. g_pWndServer->m_CriticalSection.Lock();
  96. g_pWndServer->m_ThreadList.AddTail(this);
  97. g_pWndServer->m_CriticalSection.Unlock();
  98. m_ConnectSocket.Attach(m_hSocket);
  99. m_ConnectSocket.Init();
  100. m_ConnectSocket.m_pThread = this;
  101. CString strIPAddress;
  102. UINT nPort;
  103. m_ConnectSocket.GetPeerName(strIPAddress, nPort);
  104. m_strRemoteHost=strIPAddress;
  105. m_strRemoteHost.TrimLeft ();
  106. #ifdef CONNCOUNT_VERSION
  107. if(g_localip!=strIPAddress)
  108. {
  109. CStringArray iparray;
  110. BOOL bmax=0;
  111. if(1)
  112. {
  113. // GetConnCount(&iparray);
  114. if(FindArray3(&g_connuserarray, strIPAddress)==0 && g_connuserarray.GetSize ()>g_conncount)
  115. // if( iparray.GetSize ()>g_conncount)
  116. {
  117. bmax=1;
  118. }
  119. }
  120. if(bmax)
  121. {
  122. CString ss;
  123. // ss.Format("座席版连接超数。ip:%s被拒绝。%d/%d", strIPAddress, iparray.GetSize (), g_conncount);
  124. ss.Format("座席版连接超数。ip:%s被拒绝。%d/%d", strIPAddress, g_connuserarray.GetSize (), g_conncount);
  125. WriteTextLog(ss);
  126. PostThreadMessage(WM_QUIT,0,0);
  127. return 0;
  128. }
  129. else if(FindArray3(&g_connuserarray, strIPAddress)==0)
  130. {
  131. MyLock lock("g_connuserarray");
  132. g_connuserarray.Add (strIPAddress);
  133. g_logintimearray.Add (CTime::GetCurrentTime ().Format("%H:%M:%S"));
  134. }
  135. }
  136. #endif
  137. // 通知服务器一个新的连接到达
  138. g_pWndServer->SendMessage(WM_THREADSTART, (WPARAM)this, 0);
  139. /* if(AddConn(&m_conndb, "db")==0)
  140. {
  141. WriteTextLog("打开新数据库连接失败");
  142. PostThreadMessage(WM_QUIT,0,0);
  143. return 0;
  144. }
  145. m_conndb.SetQueryTimeout(60*2);
  146. m_ConnectSocket.m_pConndb=&m_conndb;*/
  147. //获取数据库连接
  148. m_ConnectSocket.m_pdb=NULL;
  149. #if USE_ADO_OPT_DB
  150. m_ConnectSocket.m_pAdoImpl = NULL;
  151. GetOneConn(&m_ConnectSocket.m_pdb, &m_ConnectSocket.m_pAdoImpl, &m_ConnectSocket.m_dbarray, this);
  152. #else
  153. GetOneConn(&m_ConnectSocket.m_pdb, &m_ConnectSocket.m_dbarray, this);
  154. #endif//#if USE_ADO_OPT_DB
  155. /* if (g_pWndServer->CheckMaxUsers())
  156. {
  157. // m_ConnectSocket.SendResponse("421 Too many users are connected, please try again later.");
  158. WriteTextLog("连接超过最大许可");PostThreadMessage(WM_QUIT,0,0);
  159. }
  160. else
  161. if (!g_pWndServer->IsIPAddressAllowed(strIPAddress))
  162. {
  163. // m_ConnectSocket.SendResponse("421 Access denied, IP address was rejected by the server.");
  164. WriteTextLog("非法IP地址"); PostThreadMessage(WM_QUIT,0,0);
  165. }
  166. else*/
  167. {
  168. // AfxMessageBox(strIPAddress);
  169. // 发送欢迎信息给客户端
  170. // m_ConnectSocket.SendResponse("220 %s", g_pWndServer->GetWelcomeMessage());
  171. m_nTimerID = ::SetTimer(NULL, 0, 1000, TimerProc);
  172. }
  173. }
  174. catch(CException *e)
  175. {
  176. e->Delete();
  177. }
  178. return TRUE;
  179. }
  180. /********************************************************************/
  181. /* */
  182. /* Function name : ExitInstance */
  183. /* Description : Perform clean-up when the thread terminates. */
  184. /* */
  185. /********************************************************************/
  186. //线程终止
  187. extern int FindArray(CStringArray *pArray, CString Str);
  188. int CConnectThread::ExitInstance()
  189. {
  190. try
  191. {
  192. g_pWndServer->m_CriticalSection.Lock();
  193. // 从链表中删除当前线程
  194. POSITION pos = g_pWndServer->m_ThreadList.Find(this);
  195. if(pos != NULL)
  196. {
  197. g_pWndServer->m_ThreadList.RemoveAt(pos);
  198. }
  199. g_pWndServer->m_CriticalSection.Unlock();
  200. //通知服务主循环
  201. g_pWndServer->SendMessage(WM_THREADCLOSE, (WPARAM)this, 0);
  202. /*
  203. #ifdef CONNCOUNT_VERSION
  204. MyLock lock("g_connuserarray");
  205. int pos2=::FindArray (&g_connuserarray, m_strRemoteHost);
  206. if(pos2!=-1)
  207. g_connuserarray.RemoveAt (pos2);
  208. #endif
  209. */
  210. for(int i=0; i<200; i++)
  211. {
  212. if(g_pThreadPt[i]==this)
  213. {
  214. g_pThreadPt[i]=NULL;
  215. //WriteTextLog("线程退出");
  216. return CWinThread::ExitInstance();
  217. }
  218. }
  219. }
  220. catch(CException *e)
  221. {
  222. g_pWndServer->m_CriticalSection.Unlock();
  223. e->Delete();
  224. }
  225. return CWinThread::ExitInstance();
  226. }
  227. BEGIN_MESSAGE_MAP(CConnectThread, CWinThread)
  228. //{{AFX_MSG_MAP(CConnectThread)
  229. //}}AFX_MSG_MAP
  230. //ON_MESSAGE(WM_THREADMSG, OnThreadMessage)
  231. ON_THREAD_MESSAGE(WM_THREADMSG, OnThreadMessage)
  232. END_MESSAGE_MAP()
  233. /********************************************************************/
  234. /* */
  235. /* Function name : IncSentBytes */
  236. /* Description : Increment number of bytes sent by the server. */
  237. /* */
  238. /********************************************************************/
  239. void CConnectThread::IncSentBytes(int nBytes)
  240. {
  241. m_LastDataTransferTime = CTime::GetCurrentTime();
  242. m_nSentBytes += nBytes;
  243. // notify server class
  244. g_pWndServer->PostMessage(WM_THREADMSG, (WPARAM)0, (LPARAM)nBytes);
  245. }
  246. /********************************************************************/
  247. /* */
  248. /* Function name : IncReceivedBytes */
  249. /* Description : Increment number of bytes received by the server.*/
  250. /* */
  251. /********************************************************************/
  252. void CConnectThread::IncReceivedBytes(int nBytes)
  253. {
  254. m_LastDataTransferTime = CTime::GetCurrentTime();
  255. m_nReceivedBytes += nBytes;
  256. // notify server class
  257. g_pWndServer->PostMessage(WM_THREADMSG, (WPARAM)1, (LPARAM)nBytes);
  258. }
  259. /********************************************************************/
  260. /* */
  261. /* Function name : UpdateStatistic */
  262. /* Description : Specific statistics has been changed. */
  263. /* */
  264. /********************************************************************/
  265. void CConnectThread::UpdateStatistic(int nType)
  266. {
  267. // notify server class
  268. g_pWndServer->PostMessage(WM_THREADMSG, (WPARAM)2, (LPARAM)nType);
  269. }
  270. /********************************************************************/
  271. /* */
  272. /* Function name : OnThreadMessage */
  273. /* Description : Thread message received. */
  274. /* */
  275. /********************************************************************/
  276. //LRESULT CConnectThread::OnThreadMessage(WPARAM wParam, LPARAM lParam)
  277. void CConnectThread::OnThreadMessage(WPARAM wParam, LPARAM lParam)
  278. {
  279. switch(wParam)
  280. {
  281. case 0: // destroy data socket
  282. // AfxMessageBox("destroy conn");
  283. m_ConnectSocket.DestroyDataConnection();
  284. break;
  285. case 1: // quit !
  286. PostThreadMessage(WM_QUIT,0,0);
  287. break;
  288. default:
  289. break;
  290. }
  291. //return 0L;
  292. }
  293. /********************************************************************/
  294. /* */
  295. /* Function name : TimerProc */
  296. /* Description : Callback function for timer. */
  297. /* */
  298. /********************************************************************/
  299. VOID CALLBACK CConnectThread::TimerProc(HWND hwnd, UINT uMsg, UINT uIDEvent, DWORD dwTime)
  300. {
  301. CConnectThread *pThread = (CConnectThread *)AfxGetThread();
  302. if (uIDEvent == pThread->m_nTimerID)
  303. {
  304. int nConnectionTimeout = g_pWndServer->GetTimeout();
  305. // check for connection timeout
  306. CTime time = pThread->m_LastDataTransferTime;
  307. // time += CTimeSpan(0, 0, nConnectionTimeout, 0);
  308. time += CTimeSpan(0, 4, 0, 0);//10分钟不操作断线
  309. if (time < CTime::GetCurrentTime())
  310. {
  311. // WriteTextLog("用户超时退出!!!");
  312. // pThread->m_ConnectSocket.SendResponse("426 Connection timed out, aborting transfer");
  313. pThread->PostThreadMessage(WM_QUIT,0,0);
  314. }
  315. }
  316. }