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

📄 sgiapi.cpp

📁 看到联通的接口协议的dll没
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	m_sSrcNum = sSrcNum;			//源节点编码
	
	
	m_nSubmitConn = nConnCount;     //sp连接网关的连接数	
	m_nMaxSmgConn = nMaxSmgConn;    //网关连接到sp的最大数

    m_nMinWorkThreadsCount = nMinWorkThreadsCount;	// 线程池初始线程数
	m_nMaxWorkThreadsCount = nMaxWorkThreadsCount;	// 允许的线程池最大线程数

	if (m_nSubmitConn > MAX_PATH)
		m_nSubmitConn = MAX_PATH;
	if (m_nMinWorkThreadsCount > m_nMaxWorkThreadsCount)
		m_nMaxWorkThreadsCount = m_nMinWorkThreadsCount;


	//设为-1则不启动本地监听,则不接收网关的连接和消息
	//不为-1则监听,启动接受部分
	if (nLocalPort != -1)  
	{
		if (!LocalListen())
			return -1;
	}
	
	//设为-1,则不连接网关,即不发送
	//否则连接网关,预备执行发送
	if (nPeerPort != -1)   
	{
		if (!CreateConn())
			return -1;
	}
	
	//启动线程池
	pool.Start(m_nMinWorkThreadsCount, m_nMaxWorkThreadsCount);  
	
	return 0;
}

/*
   断开连接,停止线程池,释放资源
   如果Start没有启动成功,是否强制释放
*/
void CSgip::Release(BOOL forceRelease)
{
	pool.Stop(forceRelease == TRUE);   //停止线程池的处理

	ReleaseConn();                     //释放连接网关socket

	m_fStop = true;
	closesocket(serverSocket);         //关闭服务监听端口

}

/*
	提交MT消息
	nDatetime(submit包的时间戳,序列号中的第二个字段),
	与nSeq结合能够做到唯一标识一条submit消息(即使系统重新启动,nSeq重新归零).
	
	ss,				Submit消息包
	&nSeq,			该消息包的序列号中的序列号
	&nDateTime		该消息包的序列号中的时间戳

   nSeq,nDateTime都是输出参数。
   nDateTime  格式: mmddhhmmss 10位数
*/
void CSgip::Submit(sgipg_submit	ss,	unsigned &nSeq,	unsigned &nDateTime)
{
	nDateTime = sgip_get_datetime();	
	nSeq = GetSubmitSeqId();            //获取提交的序列号
	SubmitFunc(ss, nSeq, nDateTime);
}

/*
	支持群发的设置目的号码的函数.
	sUserNumber可以是单个的手机号码,或者以逗号,中划线隔开的多个号码.
	可以是以下几种类型之一,例如:"8613312345678",或"8613312345678,86133123456789",
	或"8613312345670-8613312345679",或"8613312345670,8613312345675-8613312345689",或"8613012345678,8613012345679-8613012345688,8613312312312"。
    sgipg_submit* ss,	    要群发的消息包
	const char* sUserNumber 要增加的群发手机号
*/
int CSgip::AddUserNumber(sgipg_submit* ss,const char* sUserNumber)
{
	return 0;
}


/*
   下一条要发submit消息的序列号	
   其实读取,该运行估计需要在lock下最好,
   其次为int,2 32 次方=4294967296 则复位,
   而submit可以保留2*64次方的计数
   采用long强行转化也行.
*/
unsigned int CSgip::GetSubmitSeqId()
{		
	static SeqId = 1;	
	SeqId++;
	if (SeqId == 0)	SeqId = 1;
	return SeqId;
}

	

/*
  发送消息
  获取连接网关的socket,然后,调用jobsgip处理  
*/
int CSgip::SubmitFunc(sgipg_submit ss, unsigned int nSeq, unsigned int nDateTime)
{
	m_pJob = new CJobSgip(ss, this, nSeq, nDateTime);
	
	m_worker.ProcessJob(m_pJob);
	return 0;
}

/*
  	当start,需要启动本地端口进行监听.	 
	如果不能监听就返回
*/	
bool CSgip::LocalListen()
{
	return (listen(serverSocket, m_nMaxSmgConn) != SOCKET_ERROR);

}

bool CSgip::IsValidIPAddr(LPCTSTR sIPAddr)
{
	return true;
}

/*
  创建log 文件
*/
bool CSgip::CreateLogFile()
{
	return 0;
}


/*
  获取socket用于发送submit 
*/
sgip_conn* CSgip::GetSubmitConn(int &nConnIndex)
{	
	ASSERT(m_nSubmitConn > 0);

	m_nConnIndex = 0;
	nConnIndex = 0;
	sgip_conn * ret_sgipConn = &SubmitConn[0];    //找不到返回第一个socket
	
	for(int i = 0; i < m_nSubmitConn; i++)
	{
		if (SubmitConn[i].hSocket != NULL)
		{
			if (!SubmitConn[i].fBusy)
			{				
				m_nConnIndex = i;      //保存该索引号
				nConnIndex = i;
				ret_sgipConn = &SubmitConn[i];													
				break;
			}			
		}		
	}		
	return ret_sgipConn;
}

/*
 改变连接网关的socket状态
*/
void CSgip::ChangeStatus(int nConnIndex, bool fBusy)
{
	if (nConnIndex > MAX_PATH )
		return;
	//改变连接网关的状态
	m_arrayCs.Lock();
	SubmitConn[nConnIndex].fBusy = fBusy;
	m_arrayCs.Unlock();
}


/*
   登陆smg时,先要binded,成功返回验证成功,
*/
int	 CSgip::LoginSmg(sgip_conn *pConn)
{
	sgipg_connect sc;	
	if (!pConn->fBinded)
	{			
		sgip_login_value_set(&sc, 1, (LPCTSTR)m_sUserName, (LPCTSTR)m_sPwd);
		
		int nSeq = GetSubmitSeqId();
		int iRet = sgip_login(pConn, &sc, (LPCSTR)m_sSrcNum, nSeq);  //包括bind回来处理
		if(iRet == 0)
		{		
			pConn->fBinded = true;			
			return 0;
		}
		else
		{
			pConn->nCount++;   //重连次数
			return -1;
		}		
	}
	return 0;
}

/*
   sp连向网关退出的unbind 行为   	 
*/
void CSgip::LogoutSmg(sgip_conn *pConn)
{	
	int nSeq = 0,
		iRet;
	if (pConn->fBinded)
	{
		iRet = sgip_logout(pConn, nSeq);
		if(iRet == 0)
		{
			pConn->fBinded = false;
		}			
	}
}

/****************************************************
   sp到网关的连接,采用的是长连接方式,即连接后放置在数组中
   创建socket 到该端口的连接,注意没有bind   
*/
bool CSgip::CreateConn()
{
	if (m_sUserName.IsEmpty() || m_sPeerAddr.IsEmpty()) 
		return false;
	
	for(int i = 0; i < m_nSubmitConn; i++ )
	{		
		if (sgip_connect_to_ismg((LPCTSTR)m_sPeerAddr, m_nPeerPort, &SubmitConn[i]) != SGIP_SUCCESS)
			return false;		

		if (LoginSmg(&SubmitConn[i]) == 0)//bind 包发送
		{
			SubmitConn[i].fBinded = true;
		}

	}
	return true;
}


/*
  释放所有的到网关连接
  把所有的socket都关闭.
  如果没有Unbind也需要bind?
*/
bool CSgip::ReleaseConn()
{		
	//断开连接
	for(int i = 0; i < m_nSubmitConn; i++ )
	{
		LogoutSmg(&SubmitConn[i]);				
		sgip_disconnect_from_ismg(&SubmitConn[i]);		
	}

	return true;
}

/*
  smg连接sp加入列表 
*/
void CSgip::AddSmgConn(unsigned socketHandle, unsigned port)
{	
	ASSERT(socketHandle != NULL);

	ConnInfo smgConn(socketHandle, port,GetDateTime());
	connList.push_back(smgConn);
}

/*
  移出该网关连接socket
*/
void CSgip::RemoveSmgConn(unsigned socketHandle)
{			
	list<ConnInfo>::iterator pIt;
	for (pIt = connList.begin(); pIt != connList.end(); pIt++)
	{
		if (pIt->socketHandle == socketHandle)
		{
			connList.erase(pIt);
			break;
		}
	}	
}


/********************************************************
获得日期时间函数 格式"04d-02d-02d 02d:02d:02d",
 即YYYY-MM-DD hh:mm:ss:mss,主要用于记录日志的记录的时间戳
*/
CString CSgip::GetDateTime()
{
	CString sTime;
	//CTime now = CTime::GetCurrentTime();
	//sTime = now.Format("%Y-%m-%d %H:%M:%S"));
	SYSTEMTIME systime;
	GetSystemTime(&systime);
	sTime.Format("%04d-%02d-%02d %02d:%02d:%02d:%03d", systime.wYear, systime.wMonth,
	   systime.wDay, systime.wHour, systime.wMinute, systime.wSecond, systime.wMilliseconds);
	
	return sTime;	
}


/*
  线程处理体  
*/
DWORD WINAPI CSgip::SgipServFunc(LPVOID pParam)
{
	CSgip* mySgip = (CSgip*)pParam;
	try{
		mySgip->SgipServProc();
	}
	catch(...)
	{
		
	}
	return 0;

}

/*
  处于监听accept状态.当有网关连接时,启动上行工作处理 
*/
DWORD CSgip::SgipServProc()
{	
	SOCKET	smgSocket;	
	int		iAddrSize;
	struct	sockaddr_in addr;

	iAddrSize = sizeof(addr);
	while(1)
	{	
		if (m_fStop)
			break;
		smgSocket = accept(serverSocket, (struct sockaddr *)&addr, &iAddrSize);		

		//接入端口错误,退出
		if(smgSocket == SOCKET_ERROR) 
		{
			break;	
		}				
				
		//增加socket到clist列表中
		AddSmgConn(smgSocket, addr.sin_port);
		
		//启动job工作接受信息包
		m_pJob = new CJobSgip(smgSocket, this, addr.sin_port);
		m_worker.ProcessJob(m_pJob);
	}
	return 0;
}

⌨️ 快捷键说明

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