#include "csmg.h"
#include "pub.h"
#include "main.h"
CSMG::CSMG(AnsiString SmgType)
{
m_SmgType = SmgType;
//////////////////////////////////////// 读取设置参数 ////////////////////////////////////////
TIniFile *inifile = new TIniFile(ExtractFilePath(Application->ExeName)+"setup.ini");
m_ConnectFlag = inifile->ReadInteger(m_SmgType,"ConnectFlag",1);
short openflag = inifile->ReadInteger(m_SmgType,"OpenFlag",0);
if ( openflag == 0 )
{
m_ClientState = SMG_STATE_NONE;
m_ServerState = SMG_STATE_NONE;
}
else
{
m_ClientState = SMG_STATE_NOCONNECT;
if ( m_ConnectFlag == CONNECT_MODE_LONG )
m_ServerState = SMG_STATE_NONE;
else
m_ServerState = SMG_STATE_NOCONNECT;
}
//远端服务器(网关)参数
s_RemoteIP = inifile->ReadString(m_SmgType,"RemoteIp","127.0.0.1");
s_RemotePort = inifile->ReadInteger(m_SmgType,"RemotePort",8801);
s_RemoteUserName = inifile->ReadString(m_SmgType,"RemoteUserName","1111");
s_RemotePassword = inifile->ReadString(m_SmgType,"RemotePassword","1111");
//本地服务器(SP)参数
s_LocalIP = inifile->ReadString(m_SmgType,"LocalIP","127.0.0.1");
s_LocalPort = inifile->ReadInteger(m_SmgType,"LocalPort",8802);
s_LocalUserName = inifile->ReadString(m_SmgType,"LocalUserName","2222");
s_LocalPassword = inifile->ReadString(m_SmgType,"LocalPassword","2222");
//SP接入号码
s_SPNumber = inifile->ReadString(m_SmgType,"SPNumber","111111");
//SP地区代码 (只用于SGIP,固定5位,后补0)
s_AreaCode = inifile->ReadString(m_SmgType,"AreaCode","0755");
for ( int i=s_AreaCode.Length(); i<5; i++ )
s_AreaCode = s_AreaCode + "0";
//SP企业代码,注:CMPP的s_RemoteUserName==s_SPCode
s_SPCode = inifile->ReadString(m_SmgType,"SPCode","12345");
// m_ShowCommInfoFlag = inifile->ReadInteger(m_SmgType,"ShowCommInfoFlag",0);
// m_RecordCommInfoFlag = inifile->ReadInteger(m_SmgType,"RecordCommInfoFlag",0);
s_ShowCommInfoFlag = 0;
s_RecordCommInfoFlag = 0;
m_SendNums = 0;
m_SendSuccNums = 0;
m_RecvNums = 0;
delete inifile;
///////////////////////////////////////////////////////////////////////////////////////////////////
///////////////////////////////////// 客户端初始化 ////////////////////////////////////////////////
m_ClientSocket = new TClientSocket(Application);
m_ClientSocket->Host = s_RemoteIP;
m_ClientSocket->Port = s_RemotePort;
m_ClientSocket->ClientType = ctBlocking;
m_ClientSocket->OnConnect = ClientSocketConnect;
m_ClientSocket->OnConnecting = ClientSocketConnecting;
m_ClientSocket->OnDisconnect = ClientSocketDisconnect;
m_ClientSocket->OnError = ClientSocketError;
m_ClientSocket->OnLookup = ClientSocketLookup;
m_ClientSocket->OnRead = ClientSocketRead;
m_ClientSocket->OnWrite = ClientSocketWrite;
///////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////// 服务器初始化 ///////////////////////////////////////////////
m_ServerSocket = new TServerSocket(Application);
m_ServerSocket->Port = s_LocalPort;
m_ServerSocket->ServerType = stThreadBlocking; // 阻塞方式:系统为每一个阻塞连接自动分配一个新的线程.
// m_ServerSocket->ServerType = stNonBlocking;
m_ServerSocket->OnAccept = ServerSocketAccept;
m_ServerSocket->OnClientConnect = ServerSocketClientConnect;
m_ServerSocket->OnClientDisconnect = ServerSocketClientDisconnect;
m_ServerSocket->OnClientError = ServerSocketClientError;
m_ServerSocket->OnClientRead = ServerSocketClientRead;
m_ServerSocket->OnClientWrite = ServerSocketClientWrite;
m_ServerSocket->OnListen = ServerSocketListen;
m_ServerSocket->OnGetSocket = ServerSocketGetSocket;
m_ServerSocket->OnGetThread = ServerSocketGetThread;
m_ServerSocket->OnThreadEnd = ServerSocketThreadEnd;
m_ServerSocket->OnThreadStart = ServerSocket1ThreadStart;
///////////////////////////////////////////////////////////////////////////////////////////////////
// 启动线程
if ( m_ClientState != SMG_STATE_NONE )
{
m_SendMsThread_RunFlag = THREAD_STATE_WORK;
m_SendMsThread = new CySendMsThread(true);
m_SendMsThread->m_SmgType = m_SmgType;
m_SendMsThread->Resume();
m_RecvMsThread_RunFlag = THREAD_STATE_WORK;
m_RecvMsThread = new CyRecvMsThread(true);
m_RecvMsThread->m_SmgType = m_SmgType;
m_RecvMsThread->Resume();
m_RecvMsHandleThread_RunFlag = THREAD_STATE_WORK;
m_RecvMsHandleThread = new CRecvMsHandleThread(true);
m_RecvMsHandleThread->m_SmgType = m_SmgType;
m_RecvMsHandleThread->Resume();
}
///////////////////////////////////////////////////////////////////////////////////////////////////
m_CSendMsQueue = new CyQueue(11); // 发送队列数据个数: 11
m_CSendedMsQueue = new CyQueue(4); // 已发送队列数据个数: 4
m_CRecvMsQueue = new CyQueue(2); // 接收队列数据个数: 2
///////////////////////////////////////////////////////////////////////////////////////////////////
m_ActiveTestFlag = 0;
m_ActiveTestTimes = 0;
m_Times = 0;
}
CSMG::~CSMG()
{
/*
m_ClientSocket->Socket->Close();
m_ClientSocket->Socket->Close();
delete m_ClientSocket;
delete m_ServerSocket;
*/
DisconnectToSMG();
m_ClientState = SMG_STATE_NOCONNECT;
if ( m_ClientState != SMG_STATE_NONE )
{
m_SendMsThread->m_RunFlag = THREAD_STATE_EXITING;
while( m_SendMsThread->m_RunFlag == THREAD_STATE_EXITING )
Sleep(10);
m_RecvMsThread->m_RunFlag = THREAD_STATE_EXITING;
while( m_RecvMsThread->m_RunFlag == THREAD_STATE_EXITING )
Sleep(10);
m_RecvMsHandleThread->m_RunFlag = THREAD_STATE_EXITING;
while( m_RecvMsHandleThread->m_RunFlag == THREAD_STATE_EXITING )
Sleep(10);
/* while( m_RecvMsThread_RunFlag != THREAD_STATE_STOP )
Sleep(10);
m_RecvMsHandleThread_RunFlag = THREAD_STATE_EXITING;
while( m_RecvMsHandleThread_RunFlag != THREAD_STATE_STOP )
Sleep(10);
// delete m_RecvMsHandleThread; FreeOnTerminate = true时,自动释放
*/ }
// delete CriticalSection_RecordShowCommInfoQueue;
delete m_CSendMsQueue;
delete m_CSendedMsQueue;
delete m_CRecvMsQueue;
}
bool CSMG::ConnectToSMG(void)
{
if( m_ClientState != SMG_STATE_NOCONNECT )
return TRUE;
RecordShowCommInfoQueue(LOG_TYPE_INFO,m_SmgType,"+++","连接请求","","","SMG IP="+s_RemoteIP+",SMG Port="+s_RemotePort);
try
{
m_ClientSocket->Active = true;
return true;
}
catch(...)
{
return false;
}
}
bool CSMG::DisconnectToSMG(void)
{
try
{
m_ClientSocket->Close();
return true;
}
catch(...)
{
return false;
}
}
// 链路状态检测 (定时器: 1秒)
void CSMG::CheckLinkState(short C,short T,short N)
{
/* 通信双方以客户-服务器方式建立TCP连接,用于双方信息的相互提交。
当信道上没有数据传输时,通信双方应每隔时间C发送链路检测消息以维持此连接,
当链路检测消息发出超过时间T后未收到应答,应立即再发送链路检测消息,再连续发送N-1次后仍未得到应答则断开此连接。
参数C、T、N原则上应可配置,现阶段建议取值为:C=3分钟,T=60秒,N=3。
SMGW与SP之间、SMGW与SMGW之间的消息发送后等待T秒后未收到应答,应立即重发,再连续发送N-1次后仍未得到应答则停发。现阶段建议取值为:T=60秒,N=3。
*/
if ( m_ClientState == SMG_STATE_LOGINED )
{
if ( m_Times++ > C && m_ActiveTestFlag == 0 )
{ // 每隔C分钟发送一次测试包
m_ActiveTestFlag++;
m_ActiveTestTimes = 0;