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

📄 tcp_sub.cpp

📁 这是一个在正实际应用当中运行的电力监控系统软件源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:

#include "tcp_win.h"

#ifdef _TCZ_
   #include "def.h"
   #include "wincomm.h"
#else
  #include "scada.h"
#endif

//---------------------------------------------------------------------------------------------
NODESTATUS NodeStatus[NODEMAXNUM];
//---------------------------------------------------------------------------------------------
char    ATBRouterNo=-1;//平安报文中加入的转发器节点号,当前转发器将其置为本机NodeNo,其它机器置为-1
						//当当前转发器发现自己不够转发器条件时,将其置为-2以告知其它候补转发器立即工作
						//从而不必等待判断 Router.DelayCount > R_MAXDELAYCOUNT 的延迟时间
						 
DWORD   ATBNet1IPAddr=INADDR_NONE;
//---------------------------------------------------------------------------------------------
static     NODEINFO   NodeInfo;
static     ROUTER     Router;
static     BOOL       CanBeRouter;
static     BOOL       TransTable[NODEMAXNUM][NODEMAXNUM];
//---------------------------------------------------------------------------------------------
void  InitHostNodeStatus();                //在TcpWin::SetupWindow中被调用
void  ProRcvGram(LPSTR Buf,DWORD dwIPAddr);//在TcpWin接收到一份新报文后被调用
void  UpdateNodeStatus();//在TcpWin::WMTimer中被调用
void  UpdateTransTable();//在TcpWin::WMTimer中被调用
void  DispNodeStatus();  //在TcpWin::WMTimer中被调用
void  PutAStr(HDC hdc,int y,LPSTR s1,LPSTR s2,LPSTR s3,LPSTR s4,LPSTR s5);

static void  GetNodeInfo(LPSTR Buf);              //被ProRcvGram()调用
static void  ProATBInfo(LPSTR Buf);
static void  ProTransfer(int NodeNo,LPSTR Buf);
static void  SwapNetInfo(); //交换NodeStatus中Net1与Net2中的信息,及TcpWin中的SubnetIPAddr[0]与SubnetIPAddr[1]

//---------------------------------------------------------------------------------------------
void InitHostNodeStatus(){

 int i,j;

  for(i=0;i<NODEMAXNUM;i++){
	 NodeStatus[i].Net1.IsConnect=FALSE;
	 NodeStatus[i].Net1.IPAddr=INADDR_NONE;
	 NodeStatus[i].Net1.DelayCount=0;

	 NodeStatus[i].Net2.IsConnect=FALSE;
	 NodeStatus[i].Net2.IPAddr=INADDR_NONE;
	 NodeStatus[i].Net2.DelayCount=0;
	}

  Router.InUse=FALSE;
  Router.NodeNo=-1;
  Router.DelayCount=0;

  CanBeRouter=FALSE;

  for( i=0;i<NODEMAXNUM;i++)
	  for(j=0;j<NODEMAXNUM;j++)
		   TransTable[i][j]=FALSE;

  ATBRouterNo=-1;
  ATBNet1IPAddr=INADDR_NONE;

  NetRcv[0].RxCount=NetSend.TxCount=0;
}
//---------------------------------------------------------------------------------------
void SwapNetInfo(){

  NETNODE TempNetNode;

  for(int i=0;i<NODEMAXNUM;i++)
   {
	TempNetNode=NodeStatus[i].Net1;
	NodeStatus[i].Net1=NodeStatus[i].Net2;
	NodeStatus[i].Net2=TempNetNode;
   }

  pTcpWin->SwapNetIP();
}
//---------------------------------------------------------------------------------------
void GetNodeInfo(LPSTR Buf){

   GRAMHEAD far *gHead = (GRAMHEAD far *)Buf;
   GRAMINF _FAR *gi=(GRAMINF _FAR *)(Buf+sizeof (GRAMHEAD));

   BYTE NodeType,NodeName;
   int Maxnum;

   NodeType=gHead->SourceType;//*(Buf+2);
   NodeName=gHead->SourceName;//*(Buf+3);

   if(NodeType=='F')        {   NodeInfo.NodeType='F'; Maxnum=FERTNODEMAXNUM; }
	 else if(NodeType=='H') {   NodeInfo.NodeType='H'; Maxnum=HOSTNODEMAXNUM; }
		  else                  NodeInfo.NodeType=-1;

   if(NodeInfo.NodeType!=-1)
     {
	  if((NodeName>='A') && ( NodeName<'A'+Maxnum) ){
		  NodeInfo.NodeName=NodeName;
		  NodeInfo.NodeNo=NodeName-'A';
		  NodeInfo.CmdCode=gi->CmdCode;
		  }
	  else NodeInfo.NodeType=NodeInfo.NodeName=NodeInfo.NodeNo=-1;
	 }

}
//---------------------------------------------------------------------------------------
void ProATBInfo(LPSTR Buf)
{
  //1.-----------------
  char  RouterNo=*(Buf+sizeof(GRAMHEAD)+sizeof(GRAMINF)+sizeof(CREGISTER)+2);    //7+4+4+2==17
  if( (NodeInfo.NodeType=='H')  &&
      (RouterNo>=0) && (RouterNo<HOSTNODEMAXNUM)
    )
	  	   {
			Router.InUse=TRUE;
			Router.NodeNo=RouterNo;
			Router.DelayCount=0;
		   }

  #ifndef _TCZ_
  else if( (RouterNo==-2)&&( ! ((Router.InUse==TRUE)&&(Router.NodeNo==Addr->scadainf.NodeId-'A'))))
		   {
			Router.InUse=FALSE;
			Router.NodeNo=-1;
			Router.DelayCount=0;
		   }
  #endif
  //2.-----------------
  DWORD Net1IPAddr=*(DWORD *)(Buf+sizeof(GRAMHEAD)+sizeof(GRAMINF)+sizeof(CREGISTER)+3);
  if (
			(Net1IPAddr!=INADDR_NONE)                      &&
            (NodeInfo.NodeType=='H')                       &&
		 //	(NodeInfo.NodeName==GetMainHostName ())        &&
		 //	(GetMainHostName () != ThisNodeName)           &&
			(Net1IPAddr!=pTcpWin->GetThisSubnetIPAddr(0))  &&
			(Net1IPAddr==pTcpWin->GetThisSubnetIPAddr(1))
     )
	   {
		 SwapNetInfo();
       }

}
//---------------------------------------------------------------------------------------
void H_ProRcvGram(LPSTR Buf,DWORD dwIPAddr){

  int NodeNo=0;
  
  GetNodeInfo(Buf);

  if(NodeInfo.NodeType=='H')       NodeNo=NodeInfo.NodeNo;
  else if(NodeInfo.NodeType=='F')  NodeNo=NodeInfo.NodeNo+HOSTNODEMAXNUM;
	   else return ;// Error Datagram or Mis broadcast Datagram

  if(NodeInfo.CmdCode==ATB) ProATBInfo(Buf);

  //收到x机的报文,说明本机与x机之间至少有一条网络通道通信正常
  //任何情形,只对由一条通道发来的x机的报文进行处理,但Net1优先
  if( pTcpWin->GetSubnetFromHost(dwIPAddr)==pTcpWin->GetThisSubnetIPAddr(0) )
	    {
		  NodeStatus[NodeNo].Net1.IsConnect=TRUE;
		  NodeStatus[NodeNo].Net1.IPAddr=dwIPAddr;
		  NodeStatus[NodeNo].Net1.DelayCount=0;

		  NetRcv[0].RxCount++;
		  SetRcvData (Buf);
        }
  else  if( pTcpWin->GetSubnetFromHost(dwIPAddr)==pTcpWin->GetThisSubnetIPAddr(1) )
	      {
		   NodeStatus[NodeNo].Net2.IsConnect=TRUE;
		   NodeStatus[NodeNo].Net2.IPAddr=dwIPAddr;
		   NodeStatus[NodeNo].Net2.DelayCount=0;

		   if(NodeStatus[NodeNo].Net1.IsConnect==FALSE)
			   NetRcv[0].RxCount++;
			   SetRcvData (Buf);
		  }

   #ifndef _TCZ_
   ProTransfer(NodeNo,Buf);
   #endif
}
//---------------------------------------------------------------------------------------
#ifndef _TCZ_
void ProTransfer(int NodeNo,LPSTR Buf) //处理路由转发
{
  //如果本机是当前转发器就根据转发表 ( TransTable[][] ) 进行转发  (注:直接发送给目的主机而非广播发送)
  if( (Router.InUse==TRUE)&&(Router.NodeNo==Addr->scadainf.NodeId-'A') )
	 for(int j=0;j<NODEMAXNUM;j++)
      {
		if(TransTable[NodeNo][j]==TRUE)
		  {
		   if( NodeNo>=HOSTNODEMAXNUM && j>=HOSTNODEMAXNUM)
		      if(NodeInfo.CmdCode!=ATB) break; //前置机之间只转发平安报文
		   if(NodeStatus[j].Net1.IsConnect != NodeStatus[j].Net2.IsConnect)
			  if(NodeStatus[j].Net1.IsConnect==TRUE)
					pTcpWin->SendData2Host(Buf,NodeStatus[j].Net1.IPAddr);
			  else
                {
				  if(NodeStatus[j].Net2.IsConnect==TRUE)
					pTcpWin->SendData2Host(Buf,NodeStatus[j].Net2.IPAddr);
			    }
		  }
      }
}
#endif
//---------------------------------------------------------------------------------------
void UpdateNodeStatus(){

   for(int i=0;i<NODEMAXNUM;i++)
	{
	 if(NodeStatus[i].Net1.IsConnect==TRUE)
         {
		   NodeStatus[i].Net1.DelayCount++;
		   if(NodeStatus[i].Net1.DelayCount>H_MAXDELAYCOUNT)
			{
             NodeStatus[i].Net1.IsConnect=FALSE;
			 NodeStatus[i].Net1.IPAddr=INADDR_NONE;
			 NodeStatus[i].Net1.DelayCount=0;
            }
         }
	 if(NodeStatus[i].Net2.IsConnect==TRUE)
		 {
		   NodeStatus[i].Net2.DelayCount++;
		   if(NodeStatus[i].Net2.DelayCount>H_MAXDELAYCOUNT)
			{
             NodeStatus[i].Net2.IsConnect=FALSE;
			 NodeStatus[i].Net2.IPAddr=INADDR_NONE;
			 NodeStatus[i].Net2.DelayCount=0;
            }
         }

	}


  if(Router.InUse==TRUE)
	{
	  Router.DelayCount++;
	  if(Router.DelayCount>R_MAXDELAYCOUNT)
			{
			  Router.InUse=FALSE;
			  Router.NodeNo=-1;
			  Router.DelayCount=0;
            }
    }

  #ifndef _TCZ_
   if(GetMainHostName () == ThisNodeName)
	   ATBNet1IPAddr=pTcpWin->GetThisSubnetIPAddr(0);
   else ATBNet1IPAddr=INADDR_NONE;
  #endif

⌨️ 快捷键说明

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