Channel

#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<intStockRes *> g_mapCmd;
 
StockRes * GetCmdObjectint 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::ProcessStreamconst  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::ProcessOnePacketconst 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";
	}
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值