📄 socketsvrthread.cpp
字号:
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 + -