TWSocket.cpp
上传用户:nameszq
上传日期:2014-08-12
资源大小:336k
文件大小:14k
源码类别:

金融证券系统

开发平台:

Visual C++

  1. // TWSocket.cpp : implementation file
  2. //
  3. #include "stdafx.h"
  4. #include "TWSocket.h"
  5. #include "TSCache.h"
  6. #include "StockDrv.h"
  7. #include "SpTime.h"
  8. #ifdef _DEBUG
  9. #define new DEBUG_NEW
  10. #undef THIS_FILE
  11. static char THIS_FILE[] = __FILE__;
  12. #endif
  13. /////////////////////////////////////////////////////////////////////////////
  14. // TWAutoReportThreadMain
  15. // 自动Report
  16. UINT TWAutoReportThreadMain( LPVOID pParam )
  17. {
  18. while( TRUE )
  19. {
  20. if( CTWSocket::GetInstance().GetAutoReport() && CSPTime::InTradeTime(CSPTime::GetCurrentTime().GetTime(),900) )
  21. {
  22. int nSize = CTSCache::GetInstance().GetTotalNumber();
  23. if( nSize <= 0 )
  24. continue;
  25. TW_STOCK stocks[160];
  26. memset( stocks, 0, sizeof(stocks) );
  27. int put = 0;
  28. RCV_REPORT_STRUCTEx report;
  29. for( int i=0; i<nSize; i++ )
  30. {
  31. if( CTSCache::GetInstance().GetStockByNoEx( i, &report ) )
  32. {
  33. strncpy( stocks[put].m_code, report.m_szLabel, sizeof(stocks[put].m_code) );
  34. stocks[put].m_type = typeshA;
  35. if( SH_MARKET_EX == report.m_wMarket )
  36. stocks[put].m_type = typeshA;
  37. else if( SZ_MARKET_EX == report.m_wMarket )
  38. stocks[put].m_type = typeszA;
  39. put ++;
  40. if( put >= 160 )
  41. {
  42. put = 0;
  43. CTWSocket::GetInstance().RequestReport( stocks, put );
  44. Sleep( 10000 );
  45. }
  46. }
  47. }
  48. if( put > 0 )
  49. CTWSocket::GetInstance().RequestReport( stocks, put );
  50. }
  51. if( !CTWSocket::GetInstance().IsReceiving() )
  52. {
  53. CTWCommand cmd;
  54. if( CTWSocket::GetInstance().PopCommand( cmd ) )
  55. {
  56. CTWSocket::GetInstance().RequestStockData( cmd.m_nDataType, 
  57. cmd.m_stocks.GetData(), cmd.m_stocks.GetSize(),
  58. cmd.m_nKType, cmd.m_nDataCount );
  59. }
  60. }
  61. Sleep( 30000 );
  62. }
  63. AfxEndThread( 0, TRUE );
  64. }
  65. /////////////////////////////////////////////////////////////////////////////
  66. // CTWSocket
  67. CTWSocket & CTWSocket::GetInstance()
  68. {
  69. static CTWSocket s_twsocket;
  70. return s_twsocket;
  71. }
  72. void CTWSocket::Init( )
  73. {
  74. AfxSocketInit( );
  75. }
  76. void CTWSocket::Release( )
  77. {
  78. if( GetInstance().IsWorking() )
  79. GetInstance().EndWorking();
  80. AfxSocketTerm( );
  81. }
  82. CTWSocket::CTWSocket()
  83. {
  84. m_mapCommands.InitHashTable( 2000, FALSE );
  85. m_bIsReceiving = FALSE;
  86. SetAutoReport( );
  87. AfxBeginThread( TWAutoReportThreadMain, NULL, THREAD_PRIORITY_NORMAL );
  88. }
  89. CTWSocket::~CTWSocket()
  90. {
  91. POSITION pos = m_mapCommands.GetStartPosition();
  92. while( NULL != pos )
  93. {
  94. CString rKey;
  95. void * rValue;
  96. m_mapCommands.GetNextAssoc( pos, rKey, rValue );
  97. if( NULL != rValue )
  98. {
  99. CSimpTWCommandArray * ptr = (CSimpTWCommandArray *) rValue;
  100. delete ptr;
  101. }
  102. }
  103. m_mapCommands.RemoveAll();
  104. }
  105. BOOL CTWSocket::IsWorking( )
  106. {
  107. CSingleLock lock( &m_mutex, TRUE );
  108. if( INVALID_SOCKET == m_hSocket )
  109. return FALSE;
  110. CString rPeerAddress;
  111. UINT rPeerPort;
  112. if( GetPeerName( rPeerAddress, rPeerPort)
  113. && !rPeerAddress.IsEmpty() )
  114. return TRUE;
  115. return FALSE;
  116. }
  117. BOOL CTWSocket::BeginWorking(LPCTSTR lpszHostAddress, UINT nHostPort, LPCTSTR lpszUser, LPCTSTR lpszPasswd )
  118. {
  119. CSingleLock lock( &m_mutex, TRUE );
  120. m_strHostAddress = lpszHostAddress;
  121. m_nHostPort = nHostPort;
  122. m_strUser = lpszUser;
  123. m_strPasswd = lpszPasswd;
  124. if( m_strHostAddress.IsEmpty() )
  125. return FALSE;
  126. if( !Create( ) )
  127. return FALSE;
  128. int nProxyType;
  129. CString strProxyAddress;
  130. UINT nProxyPort;
  131. AfxGetQSProfile().GetCompoundConfig( nProxyType, strProxyAddress, nProxyPort );
  132. SetProxyInfo( nProxyType, strProxyAddress, nProxyPort,
  133. AfxGetQSProfile().GetProxyUser(), AfxGetQSProfile().GetProxyPasswd() );
  134. if( !ConnectThroughProxy( m_strHostAddress, m_nHostPort ) )
  135. {
  136. m_strLastError = AfxModuleLoadString( IDS_TWSOCKET_ERRLOGIN );
  137. // 没有连接成功,以后调用无参数的BeginWorking()不再连接
  138. m_strHostAddress.Empty();
  139. m_nHostPort = 0;
  140. m_strUser.Empty();
  141. m_strPasswd.Empty();
  142. Close();
  143. return FALSE;
  144. }
  145. if( !Login(lpszUser,lpszPasswd) )
  146. {
  147. m_strLastError = AfxModuleLoadString( IDS_TWSOCKET_ERRLOGIN );
  148. // 没有连接成功,以后调用无参数的BeginWorking()不再连接
  149. m_strHostAddress.Empty();
  150. m_nHostPort = 0;
  151. m_strUser.Empty();
  152. m_strPasswd.Empty();
  153. Close();
  154. return FALSE;
  155. }
  156. return TRUE;
  157. }
  158. BOOL CTWSocket::BeginWorking( )
  159. {
  160. CSingleLock lock( &m_mutex, TRUE );
  161. if( m_strHostAddress.IsEmpty() )
  162. return FALSE;
  163. if( !Create( ) )
  164. return FALSE;
  165. int nProxyType;
  166. CString strProxyAddress;
  167. UINT nProxyPort;
  168. AfxGetQSProfile().GetCompoundConfig( nProxyType, strProxyAddress, nProxyPort );
  169. SetProxyInfo( nProxyType, strProxyAddress, nProxyPort,
  170. AfxGetQSProfile().GetProxyUser(), AfxGetQSProfile().GetProxyPasswd() );
  171. if( !ConnectThroughProxy( m_strHostAddress, m_nHostPort ) )
  172. {
  173. Close();
  174. return FALSE;
  175. }
  176. if( !Login(m_strUser,m_strPasswd) )
  177. {
  178. m_strLastError = AfxModuleLoadString( IDS_TWSOCKET_ERRLOGIN );
  179. Close();
  180. return FALSE;
  181. }
  182. return TRUE;
  183. }
  184. void CTWSocket::EndWorking( )
  185. {
  186. CSingleLock lock( &m_mutex, TRUE );
  187. ShutDown();
  188. Close();
  189. }
  190. BOOL CTWSocket::Login( LPCTSTR lpszUser, LPCTSTR lpszPasswd )
  191. {
  192. BYTE sbuffer[512];
  193. int lenSend = 0;
  194. if( lenSend = ConstructLoginBuffer(sbuffer,sizeof(sbuffer),lpszUser,lpszPasswd) )
  195. {
  196. if( Send( sbuffer, lenSend ) == lenSend )
  197. {
  198. int lenRcv = Receive( m_rbuffer, sizeof(m_rbuffer) );
  199. if( IsLoginOK( m_rbuffer, lenRcv ) )
  200. {
  201. CTSCache::GetInstance().LoadReports();
  202. RequestInit();
  203. return TRUE;
  204. }
  205. return FALSE;
  206. }
  207. }
  208. return FALSE;
  209. }
  210. int CTWSocket::SetAutoReport( int bAutoReport )
  211. {
  212. int old = m_bAutoReport;
  213. m_bAutoReport = bAutoReport;
  214. return old;
  215. }
  216. int CTWSocket::GetAutoReport( )
  217. {
  218. return m_bAutoReport;
  219. }
  220. BOOL CTWSocket::OnNewCommand( int nDataType, TW_STOCK * pStock, int nMinTimeGap )
  221. {
  222. if( nMinTimeGap <= 0 )
  223. return TRUE;
  224. CSingleLock lock( &m_mutex, TRUE );
  225. int stocktype = 0x00;
  226. if( pStock )
  227. stocktype = pStock->m_type;
  228. char stockcode[sizeof(TW_STOCK)+1];
  229. memset( stockcode, 0, sizeof(stockcode) );
  230. if( pStock )
  231. strncpy( stockcode, pStock->m_code, min(sizeof(stockcode),sizeof(pStock->m_code)) );
  232. if( strlen(stockcode) <= 0 )
  233. strncpy( stockcode, "NOCODE", sizeof(stockcode)-1 );
  234. time_t now = time(NULL);
  235. CSimpTWCommand cmd( nDataType, stocktype, stockcode, now );
  236. void * rValue = NULL;
  237. CSimpTWCommandArray * ptr = NULL;
  238. if( m_mapCommands.Lookup( stockcode, rValue ) && rValue )
  239. {
  240. ptr = (CSimpTWCommandArray *)rValue;
  241. for( int i=0; i<ptr->GetSize(); i++ )
  242. {
  243. if( cmd.m_nType == ptr->ElementAt(i).m_nType
  244. && cmd.m_nDataType == ptr->ElementAt(i).m_nDataType )
  245. {
  246. if( (cmd.m_time - ptr->ElementAt(i).m_time) < nMinTimeGap  )
  247. return FALSE;
  248. else
  249. {
  250. ptr->ElementAt(i).m_time = now;
  251. return TRUE;
  252. }
  253. }
  254. }
  255. ptr->Add( cmd );
  256. return TRUE;
  257. }
  258. ptr = new CSimpTWCommandArray();
  259. if( ptr )
  260. {
  261. ptr->SetSize( 0, TWCMD_DATATYPE_COUNT );
  262. ptr->Add( cmd );
  263. m_mapCommands.SetAt( stockcode, ptr );
  264. return TRUE;
  265. }
  266. return TRUE;
  267. }
  268. void CTWSocket::PushCommand( CTWCommand & cmd )
  269. {
  270. CSingleLock lock( &m_mutex, TRUE );
  271. m_queueCommands.Add( cmd );
  272. }
  273. BOOL CTWSocket::PopCommand( CTWCommand & cmd )
  274. {
  275. CSingleLock lock( &m_mutex, TRUE );
  276. if( m_queueCommands.GetSize() > 0 )
  277. {
  278. cmd = m_queueCommands.ElementAt(0);
  279. m_queueCommands.RemoveAt(0);
  280. return TRUE;
  281. }
  282. return FALSE;
  283. }
  284. int CTWSocket::RequestStockData( int nDataType, TW_STOCK * pStocks, int nSize, int nKType, int nDataCount )
  285. {
  286. if( m_bIsReceiving && time(NULL) - m_timeReceiveLast > 60 )
  287. m_bIsReceiving = FALSE;
  288. if( m_bIsReceiving )
  289. {
  290. CTWCommand cmd( nDataType, pStocks, nSize, nKType, nDataCount );
  291. PushCommand( cmd );
  292. return nSize;
  293. }
  294. int nRet = 0;
  295. switch( nDataType )
  296. {
  297. case RCV_REPORT:
  298. if( OnNewCommand( nDataType, pStocks, 0 ) )
  299. nRet = RequestReport( pStocks, nSize );
  300. break;
  301. case FILE_HISTORY_EX:
  302. if( OnNewCommand( nDataType, pStocks, 300 ) )
  303. nRet = RequestHistory( pStocks, nSize, nKType, nDataCount );
  304. break;
  305. case FILE_MINUTE_EX:
  306. if( OnNewCommand( nDataType, pStocks, 60 ) )
  307. nRet = RequestMinute( pStocks, nSize );
  308. break;
  309. case FILE_POWER_EX:
  310. if( OnNewCommand( nDataType, pStocks, 300 ) )
  311. nRet = RequestPower( pStocks, nSize );
  312. break;
  313. case FILE_MULTISORT_EX:
  314. if( OnNewCommand( nDataType, pStocks, 0 ) )
  315. nRet = RequestMultisort( pStocks, nSize );
  316. break;
  317. case FILE_DETAIL_EX:
  318. if( OnNewCommand( nDataType, pStocks, 60 ) )
  319. nRet = RequestDetail( pStocks, nSize );
  320. break;
  321. case FILE_BASE_EX:
  322. if( OnNewCommand( nDataType, pStocks, 300 ) )
  323. nRet = RequestBase( pStocks, nSize );
  324. break;
  325. case FILE_NEWS_EX:
  326. if( OnNewCommand( nDataType, pStocks, 60 ) )
  327. nRet = RequestNews( pStocks, nSize );
  328. break;
  329. case FILE_HTML_EX:
  330. if( OnNewCommand( nDataType, pStocks, 60 ) )
  331. nRet = RequestHtml( pStocks, nSize );
  332. break;
  333. case FILE_SOFTWARE_EX:
  334. if( OnNewCommand( nDataType, pStocks, 60 ) )
  335. nRet = RequestSoftware( pStocks, nSize );
  336. break;
  337. case FILE_SHAZQDATA_EX:
  338. if( OnNewCommand( nDataType, pStocks, 60 ) )
  339. nRet = RequestShazqdata( pStocks, nSize );
  340. break;
  341. default:;
  342. }
  343. return nRet;
  344. }
  345. int CTWSocket::RequestInit( )
  346. {
  347. TW_ASK ask;
  348. int lenSend = ConstructAskInitBuffer(ask);
  349. if( lenSend > 0 )
  350. {
  351. Send(&ask,lenSend);
  352. m_bIsReceiving = TRUE;
  353. m_timeReceiveLast = time(NULL);
  354. return 1;
  355. }
  356. return 0;
  357. }
  358. int CTWSocket::RequestReport( TW_STOCK * pStock, int nSize )
  359. {
  360. TW_STOCK stocks[32];
  361. memset( stocks, 0, sizeof(stocks) );
  362. int nMaxCount = sizeof(stocks)/sizeof(TW_STOCK);
  363. int putsize = 0;
  364. for( int i=0; i<nSize; i++ )
  365. {
  366. memcpy( &(stocks[putsize]), &(pStock[i]), sizeof(TW_STOCK) );
  367. putsize ++;
  368. if( putsize >= nMaxCount || i==nSize-1 )
  369. {
  370. TW_ASK ask;
  371. int lenSend = ConstructAskReportBuffer(ask,stocks,putsize);
  372. if( lenSend > 0 )
  373. Send(&ask,lenSend);
  374. putsize = 0;
  375. }
  376. }
  377. return nSize;
  378. }
  379. int CTWSocket::RequestHistory( TW_STOCK * pStock, int nSize, int nKType, int nDataCount )
  380. {
  381. for( int i=0; i<nSize; i++ )
  382. {
  383. BOOL bChangeStock = TRUE;
  384. BOOL bFirstRequest = TRUE;
  385. while( nDataCount > 0 )
  386. {
  387. int nCountNow = (nDataCount > 0x100 ? 0x100 : nDataCount);
  388. if( bChangeStock || bFirstRequest ) nCountNow = 1;
  389. TW_ASK ask;
  390. int lenSend = ConstructAskHistoryBuffer(ask,&(pStock[i]),nKType,nCountNow,bChangeStock,bFirstRequest);
  391. if( lenSend > 0 )
  392. Send(&ask,lenSend);
  393. nDataCount -= nCountNow;
  394. bChangeStock = FALSE;
  395. bFirstRequest = FALSE;
  396. }
  397. }
  398. return nSize;
  399. }
  400. int CTWSocket::RequestMinute( TW_STOCK * pStock, int nSize )
  401. {
  402. for( int i=0; i<nSize; i++ )
  403. {
  404. TW_ASK ask;
  405. int lenSend = ConstructAskMinuteBuffer(ask,&(pStock[i]));
  406. if( lenSend > 0 )
  407. Send(&ask,lenSend);
  408. }
  409. return nSize;
  410. }
  411. int CTWSocket::RequestPower( TW_STOCK * pStock, int nSize )
  412. {
  413. //NOTSUPPORT
  414. return 0;
  415. }
  416. int CTWSocket::RequestMultisort( TW_STOCK * pStock, int nSize )
  417. {
  418. for( int i=0; i<nSize; i++ )
  419. {
  420. TW_ASK ask;
  421. int lenSend = ConstructAskMultisortBuffer(ask, &(pStock[i]));
  422. if( lenSend > 0 )
  423. Send(&ask,lenSend);
  424. }
  425. return nSize;
  426. }
  427. int CTWSocket::RequestDetail( TW_STOCK * pStock, int nSize )
  428. {
  429. for( int i=0; i<nSize; i++ )
  430. {
  431. TW_ASK ask;
  432. int lenSend = ConstructAskDetailBuffer(ask,&(pStock[i]));
  433. if( lenSend > 0 )
  434. Send(&ask,lenSend);
  435. }
  436. return nSize;
  437. }
  438. int CTWSocket::RequestBase( TW_STOCK * pStock, int nSize )
  439. {
  440. for( int i=0; i<nSize; i++ )
  441. {
  442. TW_ASK ask;
  443. int lenSend = ConstructAskBaseBuffer(ask,&(pStock[i]));
  444. if( lenSend > 0 )
  445. {
  446. Send(&ask,lenSend);
  447. // m_bIsReceiving = TRUE;
  448. // m_timeReceiveLast = time(NULL);
  449. }
  450. }
  451. return nSize;
  452. }
  453. int CTWSocket::RequestNews( TW_STOCK * pStock, int nSize )
  454. {
  455. //NOTSUPPORT
  456. return 0;
  457. }
  458. int CTWSocket::RequestHtml( TW_STOCK * pStock, int nSize )
  459. {
  460. //NOTSUPPORT
  461. return 0;
  462. }
  463. int CTWSocket::RequestSoftware( TW_STOCK * pStock, int nSize )
  464. {
  465. //NOTSUPPORT
  466. return 0;
  467. }
  468. int CTWSocket::RequestShazqdata( TW_STOCK * pStock, int nSize )
  469. {
  470. //NOTSUPPORT
  471. return 0;
  472. }
  473. // Do not edit the following lines, which are needed by ClassWizard.
  474. #if 0
  475. BEGIN_MESSAGE_MAP(CTWSocket, CSocket)
  476. //{{AFX_MSG_MAP(CTWSocket)
  477. //}}AFX_MSG_MAP
  478. END_MESSAGE_MAP()
  479. #endif // 0
  480. /////////////////////////////////////////////////////////////////////////////
  481. // CTWSocket member functions
  482. void CTWSocket::OnClose(int nErrorCode) 
  483. {
  484. CSocket::Close( );
  485. CSocket::OnClose(nErrorCode);
  486. if( AfxGetQSProfile().GetCycleConnect() )
  487. BeginWorking();
  488. }
  489. void CTWSocket::OnConnect(int nErrorCode) 
  490. {
  491. // TODO: Add your specialized code here and/or call the base class
  492. CSocket::OnConnect(nErrorCode);
  493. }
  494. void CTWSocket::OnReceive(int nErrorCode) 
  495. {
  496. m_timeReceiveLast = time(NULL);
  497. int nReceive = Receive( m_rbuffer, sizeof(m_rbuffer) );
  498. if( nReceive > 0 )
  499. {
  500. CTSCache::GetInstance().OnReceive( m_rbuffer, nReceive );
  501. if( nReceive < 256 && TryGetLength(m_rbuffer,nReceive) < 256 ) // 收到小块包,说明大包接收完毕
  502. m_bIsReceiving = FALSE;
  503. if( nReceive == sizeof(m_rbuffer) )
  504. OnReceive(nErrorCode);
  505. }
  506. CSocket::OnReceive(nErrorCode);
  507. }
  508. void CTWSocket::OnSend(int nErrorCode) 
  509. {
  510. // TODO: Add your specialized code here and/or call the base class
  511. CSocket::OnSend(nErrorCode);
  512. }
  513. int CTWSocket::Receive(void* lpBuf, int nBufLen, int nFlags) 
  514. {
  515. // return CSocket::Receive(lpBuf, nBufLen, nFlags);
  516. if (m_pbBlocking != NULL)
  517. {
  518. WSASetLastError(WSAEINPROGRESS);
  519. return  FALSE;
  520. }
  521. int nResult;
  522. while ((nResult = CAsyncSocket::Receive(lpBuf, nBufLen, nFlags)) == SOCKET_ERROR)
  523. {
  524. if (GetLastError() == WSAEWOULDBLOCK)
  525. {
  526. if (!PumpMessages(FD_READ))
  527. return SOCKET_ERROR;
  528. }
  529. else
  530. return SOCKET_ERROR;
  531. }
  532. return nResult;
  533. }
  534. int CTWSocket::Send(const void* lpBuf, int nBufLen, int nFlags) 
  535. {
  536. // TODO: Add your specialized code here and/or call the base class
  537. return CSocket::Send(lpBuf, nBufLen, nFlags);
  538. }