#ifndef _CHANNEL_H #define _CHANNEL_H #include <string> #include <map> #include "stock.h" #include "config.h" #include "net_func.h" using namespace std; class Channel { public: Channel(); ~Channel(); void ProcessStream(const char *, uint ); void ProcessOnePacket(const uchar *, uint ); uint GetSeqId() { return ++iSeqId; } void StartRequest( ReqTimeInfo& stInfo ); void SetServerInfo( HQServerInfo * pInfo ) { m_pInfo = pInfo; } private: unsigned int packet_len; unsigned int packet_curr_pos; std::string m_sBuffer; uint iSeqId; map<uint,ReqTimeInfo> reqMap; HQServerInfo * m_pInfo; int m_iCount; }; #endif
#include "stdafx.h" #include "Channel.h" #include "response.h" #include "util.hpp" #include "stock.h" #include <memory> #include <iostream> using namespace std; map<int, StockRes *> g_mapCmd; StockRes * GetCmdObject( int iCmdId ) { StockRes * pRetRes = NULL; switch ( iCmdId ) { case CMD_HEART_BEAT: pRetRes = CreateStockHeartBeatRes(); break; /* case CMD_INSTANT_TRANS: pRetRes = CreateInstantTransRes(); break; case CMD_HIS_TRANS: pRetRes = CreateHisTransRes(); break; */ case CMD_GET_STOCK_COUNT: pRetRes = CreateGetStockCountRes(); break; case CMD_GET_STOCK_QUOTES: pRetRes = CreateGetStockQuotesRes(); break; case CMD_GET_MINUTE_DATA: pRetRes = CreateGetMinuteDataRes(); break; case CMD_GET_HIS_MINUTE_DATA: pRetRes = CreateGetHisMinuteDataRes(); break; case CMD_GET_TRANSACTION_DATA: pRetRes = CreateGetTransactionDataRes(); break; case CMD_GET_HIS_TRANSACTION_DATA: pRetRes = CreateGetHisTransactionDataRes(); break; case CMD_GET_INDEX_BARS: pRetRes = CreateGetIndexBarsRes(); break; default: pRetRes = NULL; } return pRetRes; } Channel::Channel():packet_len(0),packet_curr_pos(0),iSeqId(0),m_pInfo(NULL),m_iCount(0),m_sBuffer("") { } Channel::~Channel() { } void Channel::StartRequest( ReqTimeInfo& stInfo ) { stInfo.m_iSeqId = iSeqId; getNowStr( stInfo.m_sBeginTime ); ::QueryPerformanceCounter( &( stInfo.nBeginTime) ); reqMap[ iSeqId ] = stInfo; } void Channel::ProcessStream( const char * pData , size_t len ) { //cout << "recv:" << get_raw_string( string(pData, len) ) << endl; m_sBuffer.append( pData, len ); packet_curr_pos += len; //cout << "packet_curr_pos: " << packet_curr_pos << ", len:" << len << endl; if ( packet_len == 0 ) { if ( packet_curr_pos < 14 ) { // 还没有收到包头,继续接收包头字段 cout << "not recv head yet.packet_curr_pos: " << packet_curr_pos << endl; return; } else { // 收到了包头字段,可能是完整的包,也可能是多个包 uchar * pStart = (uchar*)m_sBuffer.c_str(); if ( pStart[1] == (uchar)0xcb && pStart[2] == (uchar)0x74 && pStart[3] == (uchar)0x00 ) { if ( pStart[0] == (uchar)0xb1 || pStart[0] == (uchar)0xbc ) { packet_len = StockRes::get_packet_len( pStart ); } } else { cout << "not valid packet. unknown header" << endl; return; } } } //cout << "packet_curr_pos:" << packet_curr_pos << endl; //判断是否收到了完整的包 if ( packet_curr_pos < packet_len ) { // 还没有收到完整的包,继续接收 //cout << "not recv full packet yet.packet_curr_pos: " << packet_curr_pos << ", packet_len:" // << packet_len << endl; return; } // 收到完整的包了,可能有1个,1.00001个包,1.5个,2.3个包,循环依次处理 uchar * pStart = (uchar*)m_sBuffer.c_str(); int iCurrLen = 0; int iCurrPacketLen = 0; while ( iCurrLen < packet_curr_pos ) { if ( iCurrLen + 14 < packet_curr_pos ) { uchar * pCurr = pStart + iCurrLen; // 有包头,获取当前包的长度 iCurrPacketLen = StockRes::get_packet_len( pCurr ); if ( iCurrLen + iCurrPacketLen <= packet_curr_pos ) { ProcessOnePacket( pCurr , iCurrPacketLen ); iCurrLen += iCurrPacketLen; iCurrPacketLen=0; } else { // 有包头,但是没有完整的包 break; } } else { // 没有包头 break; } } /* 到这里有三种情况: 1. 恰好处理完, packet_curr_pos == iCurrLen, iCurrPacketLen is 0; 2. 剩余包,包头不足14个字节。此时 packet_curr_pos > iCurrLen && iCurrLen + 14 > packet_curr_pos, iCurrPacketLen is 0; 3.剩余包,包头大于等于14个字节;此时 packet_curr_pos >= iCurrLen + 14 , iCurrPacketLen 大于 0; */ if ( packet_curr_pos == iCurrLen ) { //恰好处理完 packet_len = 0; packet_curr_pos = 0; m_sBuffer.clear(); } else { // 剩余包,包头不足14个字节 packet_curr_pos -= iCurrLen; if ( packet_curr_pos > 0 ) { m_sBuffer.erase( 0, iCurrLen ); } if ( packet_curr_pos < iCurrLen + 14 ) { packet_len = 0; } else { packet_len = iCurrPacketLen; } } } void Channel::ProcessOnePacket( const uchar * pData , size_t len ) { int cmd_id = StockRes::get_cmd_id( pData ); uint iRspSeqId = StockRes::get_seq_id( pData ); //cout << "iRspSeqId is " << iRspSeqId << ",iCmdId is " << cmd_id << endl; map<uint,ReqTimeInfo>::iterator itr = reqMap.find( iRspSeqId ); if ( itr == reqMap.end() ) { printf("error!!!!!!! unknown request:iSeqId:%u\n", iRspSeqId ); return; } else { getNowStr( itr->second.m_sEndTime ); QueryPerformanceCounter(&(itr->second.nEndTime) ); //double dcost1 = getTimeDiff( itr->second.nBeginTime, itr->second.nEndTime); //printf("获取一条行情:ServerIP:%s, port: %d, begin:%s, end:%s, dcost1:%f, pthread:%d\n", m_pInfo->szServer, // m_pInfo->iPort, itr->second.m_sBeginTime.c_str(), itr->second.m_sEndTime.c_str(), // dcost1, GetCurrentThreadId() ); ++m_iCount; } ReqTimeInfo stInfo = itr->second; if ( m_iCount == 100 ) { /* double dTotalCost = 0; map<uint,ReqTimeInfo>::const_iterator itrMap = reqMap.begin(); for ( ; itrMap != reqMap.end(); ++itrMap ) { dTotalCost += getTimeDiff( itrMap->second.nBeginTime, itrMap->second.nEndTime); //cout << "seq:" << itrMap->first << ", cur cost is " << dcost << ", begin:" << itrMap->second.m_sBeginTime // << ", end:" << itrMap->second.m_sEndTime << endl; } printf("获取行情平均耗时:ServerIP:%s, port: %d, cost:%f ms\n", m_pInfo->szServer, m_pInfo->iPort, dTotalCost/reqMap.size() ); */ m_iCount = 0; reqMap.clear(); } StockRes * pCmd = NULL; if ( g_mapCmd.find( cmd_id ) == g_mapCmd.end() ) { g_mapCmd[ cmd_id ] = GetCmdObject( cmd_id ); } pCmd = g_mapCmd[ cmd_id ]; pCmd->reset(); try { pCmd->SetRequestInfo( stInfo ); pCmd->read( pData, len ); (*pCmd)(); } catch ( StockResWrongData& e ) { } catch(...) { cout << "Command" << cmd_id << " not implemented"; } }
Channel
最新推荐文章于 2021-12-29 16:08:45 发布