⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 socketsvrthread.cpp

📁 PDA通讯网关服务器源码程序
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	int nLineID = 0;
	// 押金
	char sDeposit[nDepositLen + 1];
	// 押金
	int nDeposit = 0;
	// 开房成功标志
	bool bOpenRoomOK = false;
	// 开房响应
	st_Pack_ControlCmdRes stOpenRoomRes;
	
	LOG_DBG(MOD_SOCK_SVR, LOG_INF, "收到开房请求...");

	////////////////////////////////////////////////////////////////////////////
	// 1.检查请求包中的线路号、押金额
	////////////////////////////////////////////////////////////////////////////
	
	pOpenRoomReq = (st_Pack_OpenRoomReq *)pPackReq;

	// 检查线路号
	memset( sLineID, 0, sizeof(sLineID) );
	memcpy( sLineID, pOpenRoomReq->sLineNo, nLineIDLen);
	nLineID = atoi(sLineID);
	if( (nLineID < 1) || (nLineID > g_DataManage.GetLineNumber()) )
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "开房请求包中线路号[%d]错误", nLineID);
		return;
	}

	// 检查押金
	memset( sDeposit, 0, sizeof(sDeposit) );
	memcpy( sDeposit, pOpenRoomReq->sDeposit, nDepositLen);
	nDeposit = atof(sDeposit) * 100;
	if(nDeposit < 0)
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "开房请求包中押金额[%s]错误", sDeposit);
		return;
	}

	////////////////////////////////////////////////////////////////////////////
	// 2.开房处理
	////////////////////////////////////////////////////////////////////////////

	g_DataManage.LockTLineStatus();
	
	g_DataManage.GetTLineStatusRec(nLineID - 1, &stTLineStatusRec);
	if(!stTLineStatusRec.bUseFlag)
	{
		// 修改占用标志
		stTLineStatusRec.bUseFlag = true;

		// 修改押金和剩余押金
		stTLineStatusRec.nDeposit = nDeposit;
		stTLineStatusRec.nRemainDeposit = nDeposit;
		stTLineStatusRec.nBeginRemainDeposit = nDeposit;

		// 保存线路状态信息表到文件
		if(g_DataManage.SetTLineStatusRec(nLineID - 1, &stTLineStatusRec, true))
		{
			// 向卡消息处理线程发送开通话路消息
			g_pCommSvrThread->PostThreadMessage(WM_USER + nLineID, 1, 0);

			bOpenRoomOK = true;
		}
	}
	else
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "开房失败,因为线路[%d]已被占用", nLineID);
	}

	g_DataManage.UnlockTLineStatus();

	////////////////////////////////////////////////////////////////////////////
	// 3.发送响应包
	////////////////////////////////////////////////////////////////////////////
	
	memset( &stOpenRoomRes, 0, sizeof(stOpenRoomRes) );

	// 包长度
	_snprintf( stOpenRoomRes.sPackLen, sizeof(stOpenRoomRes.sPackLen) - 1,
		"%d", sizeof(st_Pack_ControlCmdRes) );
	// 包类型
	_snprintf(stOpenRoomRes.sPackType, sizeof(stOpenRoomRes.sPackType) - 1,
				"%d", PACK_CTRLCMD_RES);
	// 响应码
	_snprintf(stOpenRoomRes.sRespNo, sizeof(stOpenRoomRes.sRespNo) - 1,
				"%d", PACK_OPENROOM_RES);
	// 线路号
	strncpy( stOpenRoomRes.sLineNo, sLineID, sizeof(stOpenRoomRes.sLineNo) - 1 );

	if(bOpenRoomOK)
	{
		// 开房结果
		_snprintf(stOpenRoomRes.sResult, sizeof(stOpenRoomRes.sResult) - 1,
					"%d", CODE_OK);

		// 押金
		_snprintf(stOpenRoomRes.sResultValue, sizeof(stOpenRoomRes.sResultValue) - 1,
					"%.2f", nDeposit / 100.0);
		
		// 剩余押金
		_snprintf(stOpenRoomRes.sRemainValue, sizeof(stOpenRoomRes.sRemainValue) - 1,
					"%.2f", nDeposit / 100.0);

	}
	else
	{
		// 开房结果
		_snprintf(stOpenRoomRes.sResult, sizeof(stOpenRoomRes.sResult) - 1,
					"%d", CODE_ERR);

	}

	// 发送响应包
	if(m_SocketMod.SendPacket((const char *)&stOpenRoomRes, sizeof(stOpenRoomRes), hSocket))
	{
		LOG_DBG(MOD_SOCK_SVR, LOG_INF, "开房响应包已成功发出");
	}
	else
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "开房响应包发送失败,错误号:%d", GetLastError());
	}

	////////////////////////////////////////////////////////////////////////////
	// 4.如果开房成功,向其它客户端广播线路状态
	////////////////////////////////////////////////////////////////////////////
	if(bOpenRoomOK)
	{
		BoradcastLineStatus(&stTLineStatusRec);
	}

}

/************************************************************
OnClientCheckOut
功    能:结帐请求处理
性    质:private
输入参数:pPackReq - 请求包地址
		  nDataLen - 请求包长度
		  hSocket - 请求套接字
输出参数:无
返 回 值:无
************************************************************/
void CSocketSvrThread::OnClientCheckOut(void *pPackReq, int nDataLen, SOCKET hSocket)
{
	// 线路号长度
	const int nLineIDLen = 8;
	// 操作员姓名长度
	const int nOperatorLen = 20;
	// 结帐请求包
	st_Pack_CheckOutReq * pCheckOutReq = NULL;
	// 线路状态信息记录
	st_TLineStatus_Rec stTLineStatusRec;
	// 线路号
	char sLineID[nLineIDLen + 1];
	// 线路号
	int nLineID = 0;
	// 操作员
	char sOperator[nOperatorLen + 1];
	// SQL语句
	CString strSQL;
	// 结帐成功标志
	bool bCheckOutOK = false;
	// 结帐响应
	st_Pack_ControlCmdRes stCheckOutRes;


	LOG_DBG(MOD_SOCK_SVR, LOG_INF, "收到结帐请求...");
	

	////////////////////////////////////////////////////////////////////////////
	// 1.检查请求包中的线路号、取出操作员姓名
	////////////////////////////////////////////////////////////////////////////

	pCheckOutReq = (st_Pack_CheckOutReq *)pPackReq;

	// 检查线路号
	memset( sLineID, 0, sizeof(sLineID) );
	memcpy( sLineID, pCheckOutReq->sLineNo, nLineIDLen );
	nLineID = atoi(sLineID);
	if( (nLineID < 1) || (nLineID > g_DataManage.GetLineNumber()) )
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "结帐请求包中线路号[%d]错误", nLineID);
		return;
	}

	// 取出操作员姓名
	memset( sOperator, 0, sizeof(sOperator) );
	memcpy( sOperator, pCheckOutReq->sOperator,  nOperatorLen );

	////////////////////////////////////////////////////////////////////////////
	// 2.结帐处理
	////////////////////////////////////////////////////////////////////////////

	g_DataManage.LockTLineStatus();
	
	g_DataManage.GetTLineStatusRec(nLineID - 1, &stTLineStatusRec);

	if( (stTLineStatusRec.nLineState == LINE_STATE_CLOSE ) ||
		(stTLineStatusRec.nLineState == LINE_STATE_OPEN ) ||
		(stTLineStatusRec.nLineState == LINE_STATE_HANDON ) )
	{
		// 修改占用标志
		stTLineStatusRec.bUseFlag = false;

		// 保存线路状态信息表到文件
		if(g_DataManage.SetTLineStatusRec(nLineID - 1, &stTLineStatusRec, true))
		{
			
			try
			{
				// 修改该线路话单记录,设置操作员姓名、已结帐标志
				strSQL.Format("UPDATE tbill SET"
								" sOperatorName = '%s', nReckoningFlag = 1"
								" WHERE nLineID = %d AND nReckoningFlag = 0",
								sOperator, nLineID);

				m_dbConn.Execute(strSQL);

				// 向卡消息处理线程发送关闭话路消息
				g_pCommSvrThread->PostThreadMessage(WM_USER + nLineID, 0, 0);

				bCheckOutOK = true;
			}
			catch(_com_error & e)
			{
				LOG2(MOD_SOCK_SVR, LOG_ERR, "结帐时修改话单记录失败,错误:%s,SQL语句:%s",
					ADO_ERR_MSG(e), strSQL);

				// 恢复占用标志
				stTLineStatusRec.bUseFlag = true;
				if(!g_DataManage.SetTLineStatusRec(nLineID - 1, &stTLineStatusRec, true))
				{
					LOG1(MOD_SOCK_SVR, LOG_ERR, "线路[%d]结帐失败后恢复占用标志失败!", nLineID);
				}
			}

		}
	}
	else
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "结帐失败,因为线路[%d]正在通话或拨号中", nLineID);
	}

	g_DataManage.UnlockTLineStatus();

	////////////////////////////////////////////////////////////////////////////
	// 3.发送响应包
	////////////////////////////////////////////////////////////////////////////
	
	memset( &stCheckOutRes, 0, sizeof(stCheckOutRes) );

	// 包长度
	_snprintf( stCheckOutRes.sPackLen, sizeof(stCheckOutRes.sPackLen) - 1,
		"%d", sizeof(st_Pack_ControlCmdRes) );
	// 包类型
	_snprintf(stCheckOutRes.sPackType, sizeof(stCheckOutRes.sPackType) - 1,
				"%d", PACK_CTRLCMD_RES);
	// 响应码
	_snprintf(stCheckOutRes.sRespNo, sizeof(stCheckOutRes.sRespNo) - 1,
				"%d", PACK_CHECKOUT_RES);
	// 线路号
	strncpy( stCheckOutRes.sLineNo, sLineID, sizeof(stCheckOutRes.sLineNo) - 1 );

	if(bCheckOutOK)
	{
		// 成功标志
		_snprintf(stCheckOutRes.sResult, sizeof(stCheckOutRes.sResult) - 1,
					"%d", CODE_OK);

		// 押金
		_snprintf(stCheckOutRes.sResultValue, sizeof(stCheckOutRes.sResultValue) - 1,
					"%.2f", stTLineStatusRec.nDeposit / 100.0);
		
		// 剩余押金
		_snprintf(stCheckOutRes.sRemainValue, sizeof(stCheckOutRes.sRemainValue) - 1,
					"%.2f", stTLineStatusRec.nRemainDeposit / 100.0);

	}
	else
	{
		// 失败标志
		_snprintf(stCheckOutRes.sResult, sizeof(stCheckOutRes.sResult) - 1,
					"%d", CODE_ERR);

	}

	// 发送响应包
	if(m_SocketMod.SendPacket((const char *)&stCheckOutRes, sizeof(stCheckOutRes), hSocket))
	{
		LOG_DBG(MOD_SOCK_SVR, LOG_INF, "结帐响应包已成功发出");
	}
	else
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "结帐响应包发送失败,错误号:%d", GetLastError());
	}

	////////////////////////////////////////////////////////////////////////////
	// 4.如果结帐成功,向其它客户端广播线路状态
	////////////////////////////////////////////////////////////////////////////
	if(bCheckOutOK)
	{
		BoradcastLineStatus(&stTLineStatusRec);
	}

}

/************************************************************
OnClientSetDisposit
功    能:设押金请求处理
性    质:private
输入参数:pPackReq - 请求包地址
		  nDataLen - 请求包长度
		  hSocket - 请求套接字
输出参数:无
返 回 值:无
************************************************************/
void CSocketSvrThread::OnClientSetDisposit(void *pPackReq, int nDataLen, SOCKET hSocket)
{
	// 线路号长度
	const int nLineIDLen = 8;
	// 押金长度
	const int nDepositLen = 8;
	// 设押金请求包
	st_Pack_SetDepositReq * pSetDepositReq = NULL;
	// 线路状态信息记录
	st_TLineStatus_Rec stTLineStatusRec;
	// 线路号
	char sLineID[nLineIDLen + 1];
	// 线路号
	int nLineID = 0;
	// 押金
	char sDeposit[nDepositLen + 1];
	// 押金
	int nDeposit = 0;
	// 押金差额
	int nDepositDiff = 0;
	// 设押金成功标志
	bool bSetDepositOK = false;
	// 设押金响应
	st_Pack_ControlCmdRes stSetDepositRes;
	
	LOG_DBG(MOD_SOCK_SVR, LOG_INF, "收到设押金请求...");

	////////////////////////////////////////////////////////////////////////////
	// 1.检查请求包中的线路号、押金额
	////////////////////////////////////////////////////////////////////////////

	pSetDepositReq = (st_Pack_SetDepositReq *)pPackReq;

	// 检查线路号
	memset( sLineID, 0, sizeof(sLineID) );
	memcpy( sLineID, pSetDepositReq->sLineNo, nLineIDLen);
	nLineID = atoi(sLineID);
	if( (nLineID < 1) || (nLineID > g_DataManage.GetLineNumber()) )
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "设押金请求包中线路号[%d]错误", nLineID);
		return;
	}

	// 检查押金
	memset( sDeposit, 0, sizeof(sDeposit) );
	memcpy( sDeposit, pSetDepositReq->sDeposit, nDepositLen);
	nDeposit = atof(sDeposit) * 100;
	if(nDeposit < 0)
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "设押金请求包中押金额[%s]错误", sDeposit);
		return;
	}

	////////////////////////////////////////////////////////////////////////////
	// 2.设押金处理
	////////////////////////////////////////////////////////////////////////////

	g_DataManage.LockTLineStatus();
	
	g_DataManage.GetTLineStatusRec(nLineID - 1, &stTLineStatusRec);
	if(stTLineStatusRec.bUseFlag)
	{
		// 修改押金和剩余押金
		nDepositDiff = nDeposit - stTLineStatusRec.nDeposit;
		stTLineStatusRec.nDeposit = nDeposit;
		stTLineStatusRec.nRemainDeposit += nDepositDiff;
		stTLineStatusRec.nBeginRemainDeposit += nDepositDiff;

		// 重新计算通话时长
		g_pCommSvrThread->EstimateTime(&stTLineStatusRec);

		// 保存线路状态信息表到文件
		if(g_DataManage.SetTLineStatusRec(nLineID - 1, &stTLineStatusRec, true))
		{
			bSetDepositOK = true;
		}
	}
	else
	{
		LOG(MOD_SOCK_SVR, LOG_ERR, "设押金失败,因为线路[%d]未使用");
	}

	g_DataManage.UnlockTLineStatus();

	////////////////////////////////////////////////////////////////////////////
	// 3.发送响应包
	////////////////////////////////////////////////////////////////////////////
	
	memset( &stSetDepositRes, 0, sizeof(stSetDepositRes) );

	// 包长度
	_snprintf( stSetDepositRes.sPackLen, sizeof(stSetDepositRes.sPackLen) - 1,
				"%d", sizeof(st_Pack_ControlCmdRes) );
	// 包类型
	_snprintf(stSetDepositRes.sPackType, sizeof(stSetDepositRes.sPackType) - 1,
				"%d", PACK_CTRLCMD_RES);
	// 响应码
	_snprintf(stSetDepositRes.sRespNo, sizeof(stSetDepositRes.sRespNo) - 1,
				"%d", PACK_SETDEPOSIT_RES);
	// 线路号
	strncpy( stSetDepositRes.sLineNo, sLineID, sizeof(stSetDepositRes.sLineNo) - 1 );

	if(bSetDepositOK)
	{
		// 设押金结果
		_snprintf(stSetDepositRes.sResult, sizeof(stSetDepositRes.sResult) - 1,
					"%d", CODE_OK);

		// 押金
		_snprintf(stSetDepositRes.sResultValue, sizeof(stSetDepositRes.sResultValue) - 1,
					"%.2f", nDeposit / 100.0);
		
		// 剩余押金
		_snprintf(stSetDepositRes.sRemainValue, sizeof(stSetDepositRes.sRemainValue) - 1,
					"%.2f", stTLineStatusRec.nRemainDeposit / 100.0);
		
	}
	else
	{
		// 设押金结果
		_snprintf(stSetDepositRes.sResult, sizeof(stSetDepositRes.sResult) - 1,
					"%d", CODE_ERR);

	}

	// 发送响应包
	if(m_SocketMod.SendPacket((const char *)&stSetDepositRes, sizeof(stSetDepositRes), hSocket))
	{
		LOG_DBG(MOD_SOCK_SVR, LOG_INF, "设押金响应包已成功发出");
	}
	else
	{
		LOG1(MOD_SOCK_SVR, LOG_ERR, "设押金响应包发送失败,错误号:%d", GetLastError());
	}

	////////////////////////////////////////////////////////////////////////////
	// 4.如果设押金成功,向其它客户端广播线路状态
	////////////////////////////////////////////////////////////////////////////
	if(bSetDepositOK)
	{
		BoradcastLineStatus(&stTLineStatusRec);
	}

}

/************************************************************
OnClientGetLineStatus
功    能:查询话路状态请求处理
性    质:private
输入参数:pPackReq - 请求包地址
		  nDataLen - 请求包长度
		  hSocket - 请求套接字
输出参数:无
返 回 值:无
************************************************************/
void CSocketSvrThread::OnClientGetLineStatus(void *pPackReq, int nDataLen, SOCKET hSocket)
{
	// 线路状态信息包
	st_Pack_LineStatusRes stLineStatusRes;
	// 线路状态信息记录
	st_TLineStatus_Rec stTLineStatusRec;
	// 总线路数
	int nTotalLineNum = 0;
	// 当前状态包中话路数
	int nCurLineNum = 0;
	// 数据包长度
	int nPacketLen = 0;
	// 线路索引
	int nLineIndex = 0;
	// 临时变量
	int i=0;

	LOG_DBG(MOD_SOCK_SVR, LOG_INF, "收到获取话路状态信息请求...");


	nTotalLineNum = g_DataManage.GetLineNumber();

	while(nLineIndex < nTotalLineNum)
	{

		// 状态包清0
		memset( &stLineStatusRes, 0, sizeof(stLineStatusRes) );
		
		// 计算当前话路数
		if((nTotalLineNum - nLineIndex) >= MAX_LINESTATUSREC_PERPACK)
		{
			nCurLineNum = MAX_LINESTATUSREC_PERPACK;
		}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -