windows server通信软件项目

1.通信端口封装

实现串口、UDP、TCP的封装

UML类图:



源码下载:http://pan.baidu.com/s/1gdOIOnh

调用示例:

<span style="font-size:18px;"><span style="font-size:18px;">	if (pDevice->GetComType() == 0)//串口通信方式
	{
		if(pDevice->GetAutoReceive())		//主动上报
			m_pPortManage = new CComPortManage(this, pDevice->GetComPort(), pDevice->GetBaudrate());
		else							//请求上报
			m_pPortManage = new CComPortManage(pDevice->GetComPort(), pDevice->GetBaudrate());
	}
	else if (pDevice->GetComType() == 1)//TCP通信方式
	{
		if(pDevice->GetAutoReceive())		//主动上报
			m_pPortManage = new CTcpManage(this, pDevice->GetComPort(), pDevice->GetBaudrate());
		else							//请求上报
			m_pPortManage = new CTcpManage(pDevice->GetComPort(), 5009);
	}
	else if//UDP通信方式
	{
		if (psubSystem->GetComType() == 1)//主动上报
			m_pPortManage = new CUDPManage(this, psubSystem->GetNetIP(), psubSystem->GetNetSendPort(), psubSystem->GetNetRecPort());
		else//请求上报
			m_pPortManage = new CComPortManage(this, psubSystem->GetNetIP(), psubSystem->GetNetSendPort());
	}</span></span>


2.多任务并发处理

并发处理,采用生产者-消费者模型,本项目使用单生产者-多消费者模型:
生产者:接收来自前端的UDP数据包,并加入任务队列,唤醒消费者线程处理任务。

创建task:

<span style="font-size:18px;">bool CChannelManager::ReceiveChannelInfo(LONG lSessionID)
{
	///接收数据处理
	BYTE inBuf[DATALENGHT] = {0x0};
	int inBufLen = 0;
	char sSpecialData[21] = {0x0}; 
	int nReplyPort = 0; 
	char sendIp[20] = {0x0};
	if (UDP_RecBuf(inBuf, inBufLen, sSpecialData, nReplyPort, sendIp,lSessionID))
	{
		TRACE(_T("%sRec:%s\r\n"),sendIp,inBuf);
		CDataManager::Instance().SaveLogFile((char*)inBuf,_T("RecDataLog.txt"));
 		m_pTaskManager->CreateTask(inBuf, inBufLen, sSpecialData, nReplyPort, sendIp, lSessionID);
		return true;
	}
	return false;
}</span>

<span style="font-size:18px;">// 增加task
void CTaskManager::CreateTask(LPBYTE inBuf,
							  int inBufLen,
							  LPSTR sSpecialData, 
							  int nReplyPort, 
							  LPSTR sendIp,
							  LONG lSessionID)
{
	CSingleLock lock(&m_csCommunicationSync, TRUE);
	char outbuf[SQLLENGHT] = {0x0};
	int noutlen = 0;
	int nindex = 1;
	bool bLocalExecute = true;
	while(CTaskManager::ParseTask((const char *)inBuf,inBufLen,outbuf,noutlen,nindex,'{','}'))
	{
		if (nindex == 1)					//解析第一个包,判断是否继续解包
		{
			long lOrgType = 0;				// 所属机构类型	
			long lOrgID = 0;				// 所属机构编号
			long lDeviceType = 0;			// 设备类型
			long lDeviceID = 0;				// 设备编号
			int nEvent = 0;
			int ncommunicateType = 0;
			int noutFlag = 0;
			char outProbuf[SQLLENGHT] = {0x0};
			int noutProlen = 0;
			if(!CTask::ParseProtocol((const char*)outbuf, noutlen, outProbuf, noutProlen,nEvent,noutFlag,ncommunicateType, lOrgType,lOrgID,lDeviceType,lDeviceID))
			{
				return;
			}
			
			if (nEvent == 6)				//下发下级组态
			{
				if (noutFlag == 0 ||		//监控工作站发送
					(noutFlag == 1 && !CDataManager::Instance().DownOrderIsLocalExecute(lOrgType,lOrgID)))		//上级通信组态发送但不在本级执行	
				{
					CTask *pTask = new CTask();
					memcpy_s(pTask->m_sRecvBuffer,inBufLen,inBuf,inBufLen);
					pTask->m_inBufLen = inBufLen;
					memcpy_s(pTask->m_sSendIp,20,sendIp,20);
					memcpy_s(pTask->m_sSpecialData,25,sSpecialData,25);
					pTask->m_nReplyPort = nReplyPort;
					pTask->m_bLocalExecute = false;
					m_TaskList.AddTail(pTask);
					break;
				}
			}
		}

		CTask *pTask = new CTask();
		memcpy_s(pTask->m_sRecvBuffer,noutlen,outbuf,noutlen);
		pTask->m_inBufLen = noutlen;
		memcpy_s(pTask->m_sSendIp,20,sendIp,20);
		memcpy_s(pTask->m_sSpecialData,25,sSpecialData,25);
		pTask->m_nReplyPort = nReplyPort;
		pTask->m_bLocalExecute = true;
		m_TaskList.AddTail(pTask);
		memset(outbuf,0x0,SQLLENGHT);
		noutlen = 0;
		++nindex;
	}
	SetEvent(m_hReadEvent);
}</span>

消费者:在初始化时被创建消费者,等待生产者唤醒做任务。做任务时从任务队列取任务,并处理任务,等待下一次唤醒。

<span style="font-size:18px;">//task manage
UINT CTaskManager::TaskManageThreadProc(void * lParam)
{
	DWORD Event = 0;
	CTaskManager *pTaskManager = (CTaskManager *)lParam;
	pTaskManager->m_bThreadAlive = true;
	while(true)
	{
		Event = WaitForMultipleObjects(2, pTaskManager->m_hArrayEvent, FALSE, INFINITE);

		switch(Event)
		{
		case WAIT_TIMEOUT:
			break;
		case WAIT_FAILED:
			CloseHandle(pTaskManager->m_hTaskManageThread);
			pTaskManager->m_hTaskManageThread = NULL;
			pTaskManager->m_bThreadAlive = false;
			AfxEndThread(0,FALSE);
			return 1; 
		default:
			{
				if (Event - WAIT_OBJECT_0 == 0)
				{
					CloseHandle(pTaskManager->m_hTaskManageThread);
					pTaskManager->m_hTaskManageThread = NULL;
					pTaskManager->m_bThreadAlive = false;
					ResetEvent(pTaskManager->m_hExitEvent);
					AfxEndThread(0,FALSE);
					return 0;
				}

				if (Event - WAIT_OBJECT_0 == 1)
				{
					ResetEvent(pTaskManager->m_hReadEvent);
					pTaskManager->ScheduleTask();
				}
			}
			break;
		}
	}
	CloseHandle(pTaskManager->m_hTaskManageThread);
	pTaskManager->m_hTaskManageThread = NULL;
	pTaskManager->m_bThreadAlive = false;
	AfxEndThread(0,FALSE);
	return 1;
}</span>

关于生产者-消费者模型,另可参考本博客文章:http://blog.csdn.net/ceasadan/article/details/50469647

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值