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

📄 baserule.cpp

📁 此程序适用于电力系统中的网关程序
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/******************************************************************
* Copyright (c) 2004-2005, 许继日立公司
* All rights reserved.
* 
* 文件名称:baserule.cpp
* 文件标识:
* 摘    要:规约基类处理,包括通信介质的连接、读写
* 
* 当前版本:1.0
* 作    者:李龙伟  <lilongwei1@hotmail.com>
* 完成日期:2004年12月23日
*
* 取代版本:1.0 
* 原作者  :李龙伟
* 完成日期:2004年12月23日
******************************************************************/

#include "baserule.h"
#include "ext.h"

BaseRule::BaseRule(BYTE no, short rlen, short slen)
{
	m_nPortNo = no;
	m_nServer = INVALID_SOCKET;
	m_wRevLen = 0;
	m_wSendLen = 0;
	m_eCmdCode = COMMAND_NONE;		//当前通讯命令码
	m_ePreCode = m_eCmdCode;		//上次通讯命令码

	m_bSendBuf = new BYTE [slen];
	m_bRevBuf = new BYTE [rlen];
	memset(m_bSendBuf, 0, slen);
	memset(m_bRevBuf, 0, rlen);

	m_bComIndex = 0;
	m_hCom = NULL;
	memset(&m_ComInfo, 0, sizeof(COMINFO)*MAXCOMCOUNT);

	for(int i=0; i<MAXCOMCOUNT; i++)
	{
		sprintf(m_ComInfo[i].name,"COM%d",i);
	}

	//网络状态为断开
	SetNetState(GATE_UNCLOSE);

	ReadConfig();
}

//拷贝构造函数
BaseRule::BaseRule(BaseRule& b)
{
	m_nPortNo = b.m_nPortNo;
	m_nServer = b.m_nServer;
	m_wRevLen = b.m_wRevLen;
	m_wSendLen = b.m_wSendLen;
	m_eCmdCode = b.m_eCmdCode;		//当前通讯命令码
	m_ePreCode = b.m_ePreCode;		//上次通讯命令码

	m_bSendBuf = new BYTE [m_slen=b.m_slen];
	memcpy((void*)m_bSendBuf, (void*)b.m_bSendBuf, m_slen*sizeof(BYTE));
	m_bRevBuf = new BYTE [m_rlen=b.m_rlen];
	memcpy((void*)m_bRevBuf, (void*)b.m_bRevBuf, m_rlen*sizeof(BYTE));
	memset(m_bSendBuf, 0, b.m_slen);
	memset(m_bRevBuf, 0, b.m_rlen);

	m_bComIndex = b.m_bComIndex;
	m_hCom = b.m_hCom;
	memset(&b.m_ComInfo, 0, sizeof(COMINFO)*MAXCOMCOUNT);


	for(int i=0; i<MAXCOMCOUNT; i++)
	{
		sprintf(b.m_ComInfo[i].name,"COM%d",i);
	}

	//网络状态为断开
	b.SetNetState(GATE_UNCLOSE);

	b.ReadConfig();
}

BaseRule::~BaseRule()
{
	if(m_bSendBuf)
	{
		delete []m_bSendBuf;
		m_bSendBuf = NULL;
	}
	if(m_bRevBuf)
	{
		delete []m_bRevBuf;
		m_bRevBuf = NULL;
	}

	if ( m_nServer != 0 )  
	{
		FreeSocket(m_nServer);
	}
	if (m_hCom)
	{
		CloseHandle(m_hCom);
	}
}

/*====================================================================================
*                                                                                    
* Subroutine  : BaseConnect()
*                                                                                    
* Parameters  : Channel_Type   通道类型
*               
*                                                                                    
* Called from : 规约函数RuleLoop
* 
* Description : 设备连接
* 
* Return	  : 0    连接失败
*               (!0) 成功 
*                                             
* Modification: 
*				 2004-06-29: 
*                                                                                     
*====================================================================================*/
int BaseRule::BaseConnect(BYTE Channel_Type)
{
	int ret = 0;

	if (!g_bSysStop)
	{
		switch(Channel_Type)
		{
		case CHANNEL_SOCK:
			ret = SockConnect();
			break;
		case CHANNEL_RS232:
			ret = CommConnect();
			break;
		case CHANNEL_LON:
			ret = TRUE;
			break;
		}
	}

	return ret;
}

/*====================================================================================
*                                                                                    
* Subroutine  : BaseRead()
*                                                                                    
* Parameters  : 
*               
*                                                                                    
* Called from : 规约函数RuleLoop
* 
* Description : 读通道信息
* 
* Return	  : 0    读取失败
*               (!0) 成功 
*                                             
* Modification: 
*				 2004-06-29: 
*                                                                                     
*====================================================================================*/
int BaseRule::BaseRead(int t, int ms, BYTE Channel_Type)
{
	int ret = 0;

	switch(Channel_Type)
	{
	case CHANNEL_SOCK:	//-1:fail
		ret = SockRead(m_nServer, t, ms) ;
		break;
	case CHANNEL_RS232:	//-1:fail
//		Sleep(t*1000);
		ret = RS232Read(300);
		break;
//	case CHANNEL_RS485:
//		break;
	case CHANNEL_LON:
//		ret = LonRead( t );
		break;
	default:
		break;
	}
	return ret;
}

/*====================================================================================
*                                                                                    
* Subroutine  : BaseSend()
*                                                                                    
* Parameters  : 
*               
*                                                                                    
* Called from : 规约函数RuleLoop
* 
* Description : 写通道信息
* 
* Return	  : 0    写入失败
*               (!0) 成功 
*                                             
* Modification: 
*				 2004-06-29: 
*                                                                                     
*====================================================================================*/
int BaseRule::BaseSend(BYTE Channel_Type)
{
	int ret= 0;

	switch(Channel_Type)
	{
	case CHANNEL_SOCK:	//-1:fail
		ret = SockSend();
		break;
	case CHANNEL_RS232:	//-1:fail
		ret = RS232Send();
		break;
	case CHANNEL_LON:
//		ret = m_pLon->LonWriteLpdu(m_nPortNo,&m_bSendVec); //RETOK,RETFAIL
		break;
	default:
		break;
	}

	return ret;
}	

/*====================================================================================
*                                                                                    
* Subroutine  : SockConnect()
*                                                                                    
* Parameters  : 
*               
*                                                                                    
* Called from : BaseConnect
* 
* Description : 套接字连接
* 
* Return	  : 0    连接失败
*               (!0) 成功 
*                                             
* Modification: 
*				 2004-06-29: 
*                                                                                     
*====================================================================================*/
int BaseRule::SockConnect(void)
{
	unsigned long larg=1;
	int iret;
	int ipport;
	char szIP[20];
	int  asock;

	struct sockaddr_in ServerAddr;	//TCP/IP SOCKET地址数据结构

	memset(&ServerAddr,0x00,sizeof(sockaddr_in));

	if (m_nServer != INVALID_SOCKET) 
	{
		FreeSocket(m_nServer);
	}
	
	m_nServer = socket(AF_INET, SOCK_STREAM, 0);
	
	if (m_nServer==INVALID_SOCKET) 
	{
		return FALSE;
	}
	
	ServerAddr.sin_family = AF_INET;

	ipport = m_iPort;//2403;//5000;//NetAddr.port;//界面??
	ServerAddr.sin_port = htons(ipport);
//	strcpy(szIP, "10.100.100.34");
	strcpy(szIP, m_szIPAddress);//NetAddr.NetIp);//界面??
	//把字符串形式的IP地址转换成unsigned long型的整数值			
	ServerAddr.sin_addr.s_addr = inet_addr(szIP);

 	if (bind(m_nServer,(struct sockaddr *)&ServerAddr,sizeof(ServerAddr))==SOCKET_ERROR)
	{
		FreeSocket(m_nServer);
		return FALSE;
	}
	if (listen(m_nServer,8) == SOCKET_ERROR)
	{
		FreeSocket(m_nServer);
		return FALSE;
	}
	
	int sin_size=sizeof(struct sockaddr_in); 
	
	// 服务器阻塞,直到客户程序建立连接
	asock=accept(m_nServer,(struct sockaddr *)(&ServerAddr),&sin_size);

	if (asock == INVALID_SOCKET) 
	{ 
		FreeSocket(m_nServer);
		return FALSE; 
	} 
	else 
	{	
		FreeSocket(m_nServer);
		m_nServer=asock;
	}

	
	iret = ioctlsocket(m_nServer,FIONBIO,(u_long *)&larg); 
	if (iret !=0) 
	{
		FreeSocket(m_nServer);
		return FALSE;
	}

	return TRUE;
}

/*====================================================================================
*                                                                                    
* Subroutine  : SockRead()
*                                                                                    
* Parameters  : fd: 套接字
*               t:  秒
*               ms: 毫秒
*                                                                     
* Called from : BaseRead
* 
* Description : socket读通道信息
* 
* Return	  : 0    读取失败
*               (!0) 成功 
*                                             
* Modification: 
*				 2004-06-29: 
*                                                                                     
*====================================================================================*/
int BaseRule::SockRead(int fd, int t, int ms) 
{
	fd_set readbits;
	struct timeval timer;
	unsigned long lBegin = 0;
	unsigned long lEnd = 0;
	int ret = 0;
	int i = 0;
	int rlen;//isec,ims;
	int n = 256;
//	int fd = m_nServer;
	m_wRevLen = 0;
	
	timer.tv_sec = t;
	timer.tv_usec = 0; 
	FD_ZERO(&readbits);
	FD_SET(m_nServer, &readbits);
	lBegin = GetTickCount();
	ret = select(fd+1, &readbits, NULL, NULL, &timer);
	
	if (FD_ISSET(m_nServer, &readbits))	//有报文
	{
		do
		{
			Sleep(1);
			rlen = 0;
			for (i=m_wRevLen; i<n; i++) 
			{
//				m_bRevVec.push_back(0);
				ret = recv(m_nServer, (char *)&m_bRevBuf[i], 1, 0);
				if (ret == 1)
				{
					rlen ++;
					m_wRevLen++;
				}
				else 
				{
					break;
				}
			}
			
			//时间到退出
			lEnd = GetTickCount();
			unsigned long lTime = lEnd - lBegin;
			if (((t*1000 + ms) - lTime) <=0)
			{
				break;
			}
			
		} while(rlen>0);	//收不到报文退出
	}
	
	return m_wRevLen;
}

/*====================================================================================
*                                                                                    
* Subroutine  : SockSend()
*                                                                                    
* Parameters  : 
*               
*                                                                                    
* Called from : BaseSend()
* 
* Description : socket信息发送
* 
* Return	  : 0    写入失败
*               (!0) 成功 
*
* Modification: 
*				 2004-06-29: 
*                                                                                     
*====================================================================================*/
int BaseRule::SockSend()
{
	int ret = 0;
	
	if( m_wSendLen > 0 )
	{
		ret = send(m_nServer,(char *)m_bSendBuf, m_wSendLen, MSG_DONTROUTE);
	}
	
	return ret;
}

/*====================================================================================
*                                                                                    
* Subroutine  : FreeSocket()
*                                                                                    
* Parameters  : 
*				 
*                                                                                    
* Called from : Tcp103Connect()                                    
* 
* Description : 释放socket套接字
* 
* Return	  : 0   连接失败
*               !=0 连接成功                              
* Modification: 
*				 2004-11-24: 
*                                                                                     
*====================================================================================*/
int BaseRule::FreeSocket(int &s)
{
	int ret;

	ret = closesocket(s);
	
	s = 0;
	return ret;
}

/*====================================================================================
*                                                                                    
* Subroutine  : CommConnect()
*                                                                                    
* Parameters  : 
*				 
*                                                                                    
* Called from : RuleLoop()                                    
* 
* Description : 串口连接
* 
* Return	  :
*                                             
* Modification: 
*				 2004-11-10: 
*                                                                                     
*====================================================================================*/
int BaseRule::CommConnect()
{
	DCB	dcb;
//	BYTE	b=8,p=0,s=0;             // number of bits/byte, 4-8 
	char	portname[20];
	char	cportname[20];
	DWORD	dwerr,derr;
	int	comlen=0;
	int	ret = 0;

⌨️ 快捷键说明

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