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. 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 CString g_localip;
  75. extern void GetOneConn(CDatabase **m_pdb, CArray<CDatabase*,CDatabase*>*m_dbarray, CConnectThread *pThread);
  76. extern int FindArray(CStringArray *pArray, CString Str);
  77. void GetConnCount(CStringArray *pArray)
  78. {
  79. g_pWndServer->m_CriticalSection.Lock();
  80. CConnectThread *pThread;
  81. POSITION pos;
  82. pos=g_pWndServer->m_ThreadList.GetHeadPosition();
  83. while(pos)
  84. {
  85. pThread=g_pWndServer->m_ThreadList.GetNext(pos);
  86. if(g_localip==pThread->m_strRemoteHost)continue;
  87. if(::FindArray(pArray, pThread->m_strRemoteHost)==-1)
  88. pArray->Add(pThread->m_strRemoteHost);
  89. }
  90. g_pWndServer->m_CriticalSection.Unlock();
  91. }
  92. BOOL CConnectThread::InitInstance()
  93. {
  94. try
  95. {
  96. g_pWndServer->m_CriticalSection.Lock();
  97. g_pWndServer->m_ThreadList.AddTail(this);
  98. g_pWndServer->m_CriticalSection.Unlock();
  99. m_ConnectSocket.Attach(m_hSocket);
  100. m_ConnectSocket.Init();
  101. m_ConnectSocket.m_pThread = this;
  102. CString strIPAddress;
  103. UINT nPort;
  104. m_ConnectSocket.GetPeerName(strIPAddress, nPort);
  105. m_strRemoteHost=strIPAddress;
  106. m_strRemoteHost.TrimLeft ();
  107. #ifdef CONNCOUNT_VERSION
  108. if(g_localip!=strIPAddress)
  109. {
  110. CStringArray iparray;
  111. BOOL bmax=0;
  112. if(1)
  113. {
  114. // GetConnCount(&iparray);
  115. if(FindArray3(&g_connuserarray, strIPAddress)==0 && g_connuserarray.GetSize ()>g_conncount)
  116. // if( iparray.GetSize ()>g_conncount)
  117. {
  118. bmax=1;
  119. }
  120. }
  121. if(bmax)
  122. {
  123. CString ss;
  124. // ss.Format("座席版连接超数。ip:%s被拒绝。%d/%d", strIPAddress, iparray.GetSize (), g_conncount);
  125. ss.Format("座席版连接超数。ip:%s被拒绝。%d/%d", strIPAddress, g_connuserarray.GetSize (), g_conncount);
  126. WriteLogin(ss);
  127. PostThreadMessage(WM_QUIT,0,0);
  128. return 0;
  129. }
  130. else if(FindArray3(&g_connuserarray, strIPAddress)==0)
  131. {
  132. MyLock lock("g_connuserarray");
  133. g_connuserarray.Add (strIPAddress);
  134. g_logintimearray.Add (CTime::GetCurrentTime ().Format("%H:%M:%S"));
  135. }
  136. }
  137. #endif
  138. // 通知服务器一个新的连接到达
  139. g_pWndServer->SendMessage(WM_THREADSTART, (WPARAM)this, 0);
  140. /* if(AddConn(&m_conndb, "db")==0)
  141. {
  142. WriteLogin("打开新数据库连接失败");
  143. PostThreadMessage(WM_QUIT,0,0);
  144. return 0;
  145. }
  146. m_conndb.SetQueryTimeout(60*2);
  147. m_ConnectSocket.m_pConndb=&m_conndb;*/
  148. m_ConnectSocket.m_pdb=NULL;
  149. GetOneConn(&m_ConnectSocket.m_pdb, &m_ConnectSocket.m_dbarray, this);
  150. /* if (g_pWndServer->CheckMaxUsers())
  151. {
  152. // m_ConnectSocket.SendResponse("421 Too many users are connected, please try again later.");
  153. WriteLogin("连接超过最大许可");PostThreadMessage(WM_QUIT,0,0);
  154. }
  155. else
  156. if (!g_pWndServer->IsIPAddressAllowed(strIPAddress))
  157. {
  158. // m_ConnectSocket.SendResponse("421 Access denied, IP address was rejected by the server.");
  159. WriteLogin("非法IP地址"); PostThreadMessage(WM_QUIT,0,0);
  160. }
  161. else*/
  162. {
  163. // AfxMessageBox(strIPAddress);
  164. // 发送欢迎信息给客户端
  165. // m_ConnectSocket.SendResponse("220 %s", g_pWndServer->GetWelcomeMessage());
  166. m_nTimerID = ::SetTimer(NULL, 0, 1000, TimerProc);
  167. }
  168. }
  169. catch(CException *e)
  170. {
  171. e->Delete();
  172. }
  173. return TRUE;
  174. }
  175. /********************************************************************/
  176. /* */
  177. /* Function name : ExitInstance */
  178. /* Description : Perform clean-up when the thread terminates. */
  179. /* */
  180. /********************************************************************/
  181. //线程终止
  182. extern int FindArray(CStringArray *pArray, CString Str);
  183. int CConnectThread::ExitInstance()
  184. {
  185. try
  186. {
  187. g_pWndServer->m_CriticalSection.Lock();
  188. // 从链表中删除当前线程
  189. POSITION pos = g_pWndServer->m_ThreadList.Find(this);
  190. if(pos != NULL)
  191. {
  192. g_pWndServer->m_ThreadList.RemoveAt(pos);
  193. }
  194. g_pWndServer->m_CriticalSection.Unlock();
  195. //通知服务主循环
  196. g_pWndServer->SendMessage(WM_THREADCLOSE, (WPARAM)this, 0);
  197. /*
  198. #ifdef CONNCOUNT_VERSION
  199. MyLock lock("g_connuserarray");
  200. int pos2=::FindArray (&g_connuserarray, m_strRemoteHost);
  201. if(pos2!=-1)
  202. g_connuserarray.RemoveAt (pos2);
  203. #endif
  204. */
  205. for(int i=0; i<200; i++)
  206. {
  207. if(g_pThreadPt[i]==this)
  208. {
  209. g_pThreadPt[i]=NULL;
  210. //WriteLogin("线程退出");
  211. return CWinThread::ExitInstance();
  212. }
  213. }
  214. }
  215. catch(CException *e)
  216. {
  217. g_pWndServer->m_CriticalSection.Unlock();
  218. e->Delete();
  219. }
  220. return CWinThread::ExitInstance();
  221. }
  222. BEGIN_MESSAGE_MAP(CConnectThread, CWinThread)
  223. //{{AFX_MSG_MAP(CConnectThread)
  224. //}}AFX_MSG_MAP
  225. ON_THREAD_MESSAGE(WM_THREADMSG, OnThreadMessage)
  226. END_MESSAGE_MAP()
  227. /********************************************************************/
  228. /* */
  229. /* Function name : IncSentBytes */
  230. /* Description : Increment number of bytes sent by the server. */
  231. /* */
  232. /********************************************************************/
  233. void CConnectThread::IncSentBytes(int nBytes)
  234. {
  235. m_LastDataTransferTime = CTime::GetCurrentTime();
  236. m_nSentBytes += nBytes;
  237. // notify server class
  238. g_pWndServer->PostMessage(WM_THREADMSG, (WPARAM)0, (LPARAM)nBytes);
  239. }
  240. /********************************************************************/
  241. /* */
  242. /* Function name : IncReceivedBytes */
  243. /* Description : Increment number of bytes received by the server.*/
  244. /* */
  245. /********************************************************************/
  246. void CConnectThread::IncReceivedBytes(int nBytes)
  247. {
  248. m_LastDataTransferTime = CTime::GetCurrentTime();
  249. m_nReceivedBytes += nBytes;
  250. // notify server class
  251. g_pWndServer->PostMessage(WM_THREADMSG, (WPARAM)1, (LPARAM)nBytes);
  252. }
  253. /********************************************************************/
  254. /* */
  255. /* Function name : UpdateStatistic */
  256. /* Description : Specific statistics has been changed. */
  257. /* */
  258. /********************************************************************/
  259. void CConnectThread::UpdateStatistic(int nType)
  260. {
  261. // notify server class
  262. g_pWndServer->PostMessage(WM_THREADMSG, (WPARAM)2, (LPARAM)nType);
  263. }
  264. /********************************************************************/
  265. /* */
  266. /* Function name : OnThreadMessage */
  267. /* Description : Thread message received. */
  268. /* */
  269. /********************************************************************/
  270. void CConnectThread::OnThreadMessage(WPARAM wParam, LPARAM lParam)
  271. {
  272. switch(wParam)
  273. {
  274. case 0: // destroy data socket
  275. // AfxMessageBox("destroy conn");
  276. m_ConnectSocket.DestroyDataConnection();
  277. break;
  278. case 1: // quit !
  279. PostThreadMessage(WM_QUIT,0,0);
  280. break;
  281. default:
  282. break;
  283. }
  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. }