📄 tcp_sub.cpp
字号:
#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 + -