ConnectThread.cpp 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347
  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. IMPLEMENT_DYNCREATE(CConnectThread, CWinThread)
  33. /********************************************************************/
  34. /* */
  35. /* Function name : CConnectThread::CConnectThread */
  36. /* Description : Constructor */
  37. /* */
  38. /********************************************************************/
  39. CConnectThread::CConnectThread()
  40. {
  41. m_nReceivedBytes = 0;
  42. m_nSentBytes = 0;
  43. m_nTimerID = 0;
  44. m_LastDataTransferTime = CTime::GetCurrentTime();
  45. }
  46. /********************************************************************/
  47. /* */
  48. /* Function name : CConnectThread::~CConnectThread */
  49. /* Description : Destructor */
  50. /* */
  51. /********************************************************************/
  52. CConnectThread::~CConnectThread()
  53. {
  54. }
  55. /********************************************************************/
  56. /* */
  57. /* Function name : InitInstance */
  58. /* Description : Perform tasks that must be completed when the */
  59. /* thread is first created. */
  60. /* */
  61. /********************************************************************/
  62. //初始化线程
  63. int FindArray3(CStringArray *pArray, CString Str)
  64. {
  65. int count=0;
  66. for(int i=0; i<pArray->GetSize (); i++)
  67. {
  68. if(pArray->ElementAt (i)==Str)
  69. count++;
  70. }
  71. return count;
  72. }
  73. //extern CString g_localip;
  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. WriteLogin(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. WriteLogin("打开新数据库连接失败");
  142. PostThreadMessage(WM_QUIT,0,0);
  143. return 0;
  144. }
  145. m_conndb.SetQueryTimeout(60*2);
  146. m_ConnectSocket.m_pConndb=&m_conndb;*/
  147. m_ConnectSocket.m_pdb=NULL;
  148. GetOneConn(&m_ConnectSocket.m_pdb, &m_ConnectSocket.m_dbarray, this);
  149. /* if (g_pWndServer->CheckMaxUsers())
  150. {
  151. // m_ConnectSocket.SendResponse("421 Too many users are connected, please try again later.");
  152. WriteLogin("连接超过最大许可");PostThreadMessage(WM_QUIT,0,0);
  153. }
  154. else
  155. if (!g_pWndServer->IsIPAddressAllowed(strIPAddress))
  156. {
  157. // m_ConnectSocket.SendResponse("421 Access denied, IP address was rejected by the server.");
  158. WriteLogin("非法IP地址"); PostThreadMessage(WM_QUIT,0,0);
  159. }
  160. else*/
  161. {
  162. // AfxMessageBox(strIPAddress);
  163. // 发送欢迎信息给客户端
  164. // m_ConnectSocket.SendResponse("220 %s", g_pWndServer->GetWelcomeMessage());
  165. m_nTimerID = ::SetTimer(NULL, 0, 1000, TimerProc);
  166. }
  167. }
  168. catch(CException *e)
  169. {
  170. e->Delete();
  171. }
  172. return TRUE;
  173. }
  174. /********************************************************************/
  175. /* */
  176. /* Function name : ExitInstance */
  177. /* Description : Perform clean-up when the thread terminates. */
  178. /* */
  179. /********************************************************************/
  180. //线程终止
  181. //extern int FindArray(CStringArray *pArray, CString Str);
  182. int CConnectThread::ExitInstance()
  183. {
  184. try
  185. {
  186. g_pWndServer->m_CriticalSection.Lock();
  187. // 从链表中删除当前线程
  188. POSITION pos = g_pWndServer->m_ThreadList.Find(this);
  189. if(pos != NULL)
  190. {
  191. g_pWndServer->m_ThreadList.RemoveAt(pos);
  192. }
  193. g_pWndServer->m_CriticalSection.Unlock();
  194. //通知服务主循环
  195. g_pWndServer->SendMessage(WM_THREADCLOSE, (WPARAM)this, 0);
  196. /*
  197. #ifdef CONNCOUNT_VERSION
  198. MyLock lock("g_connuserarray");
  199. int pos2=::FindArray (&g_connuserarray, m_strRemoteHost);
  200. if(pos2!=-1)
  201. g_connuserarray.RemoveAt (pos2);
  202. #endif
  203. */
  204. for(int i=0; i<200; i++)
  205. {
  206. if(g_pThreadPt[i]==this)
  207. {
  208. g_pThreadPt[i]=NULL;
  209. //WriteLogin("线程退出");
  210. return CWinThread::ExitInstance();
  211. }
  212. }
  213. }
  214. catch(CException *e)
  215. {
  216. g_pWndServer->m_CriticalSection.Unlock();
  217. e->Delete();
  218. }
  219. return CWinThread::ExitInstance();
  220. }
  221. BEGIN_MESSAGE_MAP(CConnectThread, CWinThread)
  222. //{{AFX_MSG_MAP(CConnectThread)
  223. //}}AFX_MSG_MAP
  224. ON_MESSAGE(WM_THREADMSG, OnThreadMessage)
  225. END_MESSAGE_MAP()
  226. /********************************************************************/
  227. /* */
  228. /* Function name : IncSentBytes */
  229. /* Description : Increment number of bytes sent by the server. */
  230. /* */
  231. /********************************************************************/
  232. void CConnectThread::IncSentBytes(int nBytes)
  233. {
  234. m_LastDataTransferTime = CTime::GetCurrentTime();
  235. m_nSentBytes += nBytes;
  236. // notify server class
  237. g_pWndServer->PostMessage(WM_THREADMSG, (WPARAM)0, (LPARAM)nBytes);
  238. }
  239. /********************************************************************/
  240. /* */
  241. /* Function name : IncReceivedBytes */
  242. /* Description : Increment number of bytes received by the server.*/
  243. /* */
  244. /********************************************************************/
  245. void CConnectThread::IncReceivedBytes(int nBytes)
  246. {
  247. m_LastDataTransferTime = CTime::GetCurrentTime();
  248. m_nReceivedBytes += nBytes;
  249. // notify server class
  250. g_pWndServer->PostMessage(WM_THREADMSG, (WPARAM)1, (LPARAM)nBytes);
  251. }
  252. /********************************************************************/
  253. /* */
  254. /* Function name : UpdateStatistic */
  255. /* Description : Specific statistics has been changed. */
  256. /* */
  257. /********************************************************************/
  258. void CConnectThread::UpdateStatistic(int nType)
  259. {
  260. // notify server class
  261. g_pWndServer->PostMessage(WM_THREADMSG, (WPARAM)2, (LPARAM)nType);
  262. }
  263. /********************************************************************/
  264. /* */
  265. /* Function name : OnThreadMessage */
  266. /* Description : Thread message received. */
  267. /* */
  268. /********************************************************************/
  269. LRESULT CConnectThread::OnThreadMessage(WPARAM wParam, LPARAM lParam)
  270. {
  271. switch(wParam)
  272. {
  273. case 0: // destroy data socket
  274. // AfxMessageBox("destroy conn");
  275. m_ConnectSocket.DestroyDataConnection();
  276. break;
  277. case 1: // quit !
  278. PostThreadMessage(WM_QUIT,0,0);
  279. break;
  280. default:
  281. break;
  282. }
  283. return 0L;
  284. }
  285. /********************************************************************/
  286. /* */
  287. /* Function name : TimerProc */
  288. /* Description : Callback function for timer. */
  289. /* */
  290. /********************************************************************/
  291. VOID CALLBACK CConnectThread::TimerProc(HWND hwnd, UINT uMsg, UINT uIDEvent, DWORD dwTime)
  292. {
  293. CConnectThread *pThread = (CConnectThread *)AfxGetThread();
  294. if (uIDEvent == pThread->m_nTimerID)
  295. {
  296. int nConnectionTimeout = g_pWndServer->GetTimeout();
  297. // check for connection timeout
  298. CTime time = pThread->m_LastDataTransferTime;
  299. // time += CTimeSpan(0, 0, nConnectionTimeout, 0);
  300. time += CTimeSpan(0, 4, 0, 0);//10分钟不操作断线
  301. if (time < CTime::GetCurrentTime())
  302. {
  303. // WriteLogin("用户超时退出!!!");
  304. // pThread->m_ConnectSocket.SendResponse("426 Connection timed out, aborting transfer");
  305. pThread->PostThreadMessage(WM_QUIT,0,0);
  306. }
  307. }
  308. }