You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1028 lines
28 KiB
C++

2 years ago
/************************************************************************************
*
* Copyright (C) 2002-2003 SCADA Control Technology Co., Ltd. All rights reserved.
*
* $Source: /opt/CVS_ROOT_PGC_EX2000/commserver/windows/widgets/udpping.cpp,v $
*
* $Author: zhuzhenhua $
*
* $Date: 2006/08/07 03:16:49 $
*
* $Revision: 1.2 $
*
* $State: Exp $
*
* $Name: $
*
* $Locker: $
*
**************************************************************************************/
//***************************************************************
//* udpping.cpp *
//* Liangchu Lee 1999.12.20 *
//***************************************************************
//************************修 改 提 示****************************
//1. wen 2002.11.11 前置机为备用机B时主机退出无法进行切换
// 问题当前置机A为主机下发退出系统后备用前置机无法把自身切换
// 为主机。
// 描述:修改读取函数部分 UdpPingReaddata(void)。
// 结果增加判断长时间收不到对方PING包置其下发标志为FALSE。
//2. wen 2003.04.21 服务器和前置机共处一台机器中,会出现绑定失败。
// 问题前置机后启动ping接收端口不能正常工作。
// 描述:服务器、前置机共处一台机器,当前置机后启动,绑定失败,
// 地址被服务器使用。错误信息=10048(套接字地址被使用)。
// 结果设置socket属性为SO_REUSEADDR地址可重用。
2 years ago
//***************************************************************
#include "commport.h"
#include "udpping.h"
#include "tcphost.h"
UDP_PING_INFO UdpPing;
int gUdpPingReadPort;
int gUdpPingWritePort;
int gUdpPingInitOk = FALSE;
int gPingWaitCnt = 0;
int gSendTxdDataFendIdx = 0;
//int gtestread = 1;
extern char IniFilePath[256];
void UdpPingTimer(void)
{
if(gUdpPingInitOk == TRUE)
{
UdpPingReaddata();
#ifdef MACRO_NETPING_P2P
UdpPingSendDataP2P();
#else
UdpPingSendData();
#endif
}
else
{
gUdpPingInitOk = UdpPingInit();
}
}
BOOL UdpPingInit(void)
{
static BOOL bFirst = TRUE;
int i, tmp_len;
struct sockaddr_in *cliaddr;
//struct hostent *test;
#ifndef MACRO_NETPING_P2P
BOOL bBroadcast = TRUE; // 是否广播方式发送数据报
2 years ago
#endif
int timeout = 1000; // 超时
2 years ago
char szConfig[256];
#ifdef OS_LINUX
strcpy(szConfig, "config.ini");
#else
//GetCurrentDirectory(sizeof(szDir), szDir);
sprintf(szConfig, "%s/config.ini", IniFilePath);
#endif
gUdpPingReadPort = GetPrivateProInt("网络设置", "PING接收端口", 8124, szConfig);
gUdpPingWritePort = GetPrivateProInt("网络设置", "PING发送端口", 8123, szConfig);
2 years ago
//test = gethostbyname(pFendMsg->Name);
for(i = 0; i < MAX_ADDR; i++)
{
if(bFirst == TRUE)
{
UdpPing.sSocket[i] = INVALID_SOCKET;
}
else
{
if(INVALID_SOCKET != UdpPing.sSocket[i])
{
continue;
}
}
cliaddr = &UdpPing.CliAddr;
UdpPing.sSocket[i] = socket(AF_INET, SOCK_DGRAM, 0);
if(UdpPing.sSocket[i] < 0)
{
UdpPing.sSocket[i] = INVALID_SOCKET;
continue;
}
#ifdef OS_LINUX
// wen 2005.07.08 将socket设置为非阻塞模式
2 years ago
tmp = fcntl(UdpPing.sSocket[i], F_GETFL, 0);
fcntl(UdpPing.sSocket[i], F_SETFL, tmp|O_NONBLOCK);
#endif
#ifndef MACRO_NETPING_P2P
// wen 2006.04.28 不使用广播发送ping包
2 years ago
bBroadcast = TRUE;
setsockopt(UdpPing.sSocket[i], SOL_SOCKET, SO_BROADCAST, (char*)&bBroadcast, sizeof(bBroadcast));
#endif
tmp_len = 1;
setsockopt(UdpPing.sSocket[i], SOL_SOCKET, SO_REUSEADDR, (char*)&tmp_len, sizeof(int));
setsockopt(UdpPing.sSocket[i], SOL_SOCKET, SO_SNDTIMEO, (char*)&timeout, sizeof(timeout));
setsockopt(UdpPing.sSocket[i], SOL_SOCKET, SO_RCVTIMEO, (char*)&timeout, sizeof(timeout));
memset((char *)cliaddr, 0, sizeof(*cliaddr));
cliaddr->sin_family = AF_INET;
cliaddr->sin_addr.s_addr = htonl(INADDR_ANY);
cliaddr->sin_port = htons(INADDR_ANY);
if(bind(UdpPing.sSocket[i], (struct sockaddr *)cliaddr, sizeof(*cliaddr)) != 0)
//if((tmp = bind(UdpPing.sSocket[i], (struct sockaddr *)cliaddr, sizeof(*cliaddr))) == SOCKET_ERROR)
{
CloseNetSocket(UdpPing.sSocket[i]);
UdpPing.sSocket[i] = INVALID_SOCKET;
continue;
}
}
cliaddr = &UdpPing.CliAddr;
if(bFirst != TRUE)
{
if(INVALID_SOCKET != UdpPing.rSocket)
{
return TRUE;
}
}
else
{
bFirst = FALSE;
}
UdpPing.rSocket = socket(AF_INET, SOCK_DGRAM, 0);
if(UdpPing.rSocket < 0)
{
UdpPing.rSocket = INVALID_SOCKET;
return FALSE;
}
// wen 2003.04.21 服务器和前置机共处一台机器中,会出现绑定失败。套接字地址被使用
2 years ago
tmp_len = 1;
setsockopt(UdpPing.rSocket, SOL_SOCKET, SO_REUSEADDR, (char*)&tmp_len, sizeof(int));
memset((char *)cliaddr, 0, sizeof(*cliaddr));
cliaddr->sin_family = AF_INET;
cliaddr->sin_addr.s_addr = htonl(INADDR_ANY);
cliaddr->sin_port = htons(gUdpPingReadPort);
if(bind(UdpPing.rSocket, (struct sockaddr *)cliaddr, sizeof(*cliaddr)) != 0)
//if((tmp = bind(UdpPing.rSocket, (struct sockaddr *)cliaddr, sizeof(*cliaddr))) == SOCKET_ERROR)
{
CloseNetSocket(UdpPing.rSocket);
UdpPing.rSocket = INVALID_SOCKET;
return FALSE;
}
return TRUE;
}
void UdpPingSendData(void)
{
//char szDbg[256];
static int cnt = 0;
int i, sendlen;
struct sockaddr_in *servaddr;
PINGINFORMATION PingData;
// wen 2002.07.11
BOOL bSendFlag = FALSE;
TCP_LINK_DEF *pHostLink;
FEND_DEF *pFendMsg;
SIO_PARAM_DEF *pSioParam;
cnt++;
if((cnt * TIMER_CNT) < 1000)
{
return;
}
cnt = 0;
// 获取全局变量,通过函数调用
2 years ago
pHostLink = GetHostLinkPtr();
pFendMsg = GetFendMsgPtr();
//if(pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] == TRUE)
//{
// sprintf(szDbg, "FendIdx=%d is Txd Fend.", pFendMsg->FendIdx);
// DebugPrint(szDbg);
//}
memmove((char*)PingData.barrRandom, PINGRANDOM, MAX_RANDOM);
if(pFendMsg->FendIdx == 0)
{
strcpy((char*)PingData.szNodeName, "FENDA");
}
else
{
strcpy((char*)PingData.szNodeName, "FENDB");
}
PingData.bNodeType = FEND_TYPE;
PingData.wNodeID = pFendMsg->FendIdx;
PingData.inetMask = pFendMsg->HostIpAddr[0];
PingData.inetAddr = pFendMsg->AllIpAddr[0];
PingData.dwStatus = 0;
if(gPingWaitCnt < MAX_DELAYTIME)
{
gPingWaitCnt++;
}
//sprintf(szDbg, "WaitCnt=%d, Txd[0]=%d, Txd[1]=%d, Exist[0]=%d, Exist[1]=%d",
// gPingWaitCnt, pFendMsg->SendTxdDataFlag[0], pFendMsg->SendTxdDataFlag[1],
// pFendMsg->FendExistFlag[0], pFendMsg->FendExistFlag[1]);
//DebugPrint(szDbg);
if(gPingWaitCnt == 5)
{
if((pFendMsg->SendTxdDataFlag[0] == 0)
&& (pFendMsg->SendTxdDataFlag[1] == 0))
{
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.04.22 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
2 years ago
//pFendMsg->SendTxdDataFlag[0] = FALSE;
//pFendMsg->SendTxdDataFlag[1] = FALSE;
//pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
//=======================================================================
if(pFendMsg->iPortMask)
{
pSioParam = GetSioParamPtr();
for(i=0; i<DEFAULT_MAX_PORT_NUM; i++)
{
if(pFendMsg->iPortMask & (0x00000001 << i))
{
if(pSioParam[i].Status)
{
break;
}
}
}
}
else
{
i = DEFAULT_MAX_PORT_NUM;
}
if(i >= DEFAULT_MAX_PORT_NUM)
{
pFendMsg->SendTxdDataFlag[0] = FALSE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
}
if((gSendTxdDataFendIdx == 0) && (gPingWaitCnt > 10))
{
if((pFendMsg->SendTxdDataFlag[0] == 0)
&& (pFendMsg->SendTxdDataFlag[1] == 0))
{
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.04.22 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
2 years ago
//pFendMsg->SendTxdDataFlag[0] = FALSE;
//pFendMsg->SendTxdDataFlag[1] = FALSE;
//pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
//=======================================================================
if(pFendMsg->iPortMask)
{
pSioParam = GetSioParamPtr();
for(i=0; i<DEFAULT_MAX_PORT_NUM; i++)
{
if(pFendMsg->iPortMask & (0x00000001 << i))
{
if(pSioParam[i].Status)
{
break;
}
}
}
}
else
{
i = DEFAULT_MAX_PORT_NUM;
}
if(i >= DEFAULT_MAX_PORT_NUM)
{
pFendMsg->SendTxdDataFlag[0] = FALSE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
if(pFendMsg->FendExistFlag[0] == FALSE)
{
pFendMsg->SendTxdDataFlag[0] = FALSE;
}
if(pFendMsg->FendExistFlag[1] == FALSE)
{
pFendMsg->SendTxdDataFlag[1] = FALSE;
}
// wen 2002.11.25 连接服务器慢的系统会出现切换不成功
2 years ago
/*
switch(pFendMsg->LinkStatus[1]*2 + pFendMsg->LinkStatus[0])
{
case 0x01:
pFendMsg->SendTxdDataFlag[0] = TRUE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
break;
case 0x02:
pFendMsg->SendTxdDataFlag[0] = FALSE;
pFendMsg->SendTxdDataFlag[1] = TRUE;
break;
}
*/
}
//DebugPrint("UdpPingSendData Begin...");
// 字节顺序转换
2 years ago
PingData.wNodeID = SequenceHostToRtuWord(PingData.wNodeID);
for(i = 0; i < MAX_ADDR; i++)
{
if(INVALID_SOCKET == UdpPing.sSocket[i])
{
continue;
}
PingData.inetMask = pFendMsg->HostIpAddr[i];
PingData.inetAddr = pFendMsg->AllIpAddr[i];
PingData.dwStatus = (pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] ? 4 : 0)
+ (pHostLink[1].InitOk ? 2 : 0) + (pHostLink[0].InitOk ? 1 : 0) + 0x30000;
switch(gSendTxdDataFendIdx)
{
case 1: // 前置机 A 下发数据
2 years ago
if(pFendMsg->SendTxdDataFlag[0] == 0)
{
pFendMsg->SendTxdDataFlag[1] = FALSE;
PingData.dwStatus += 0x10;
}
else
{
if(pFendMsg->SendTxdDataFlag[0]
&& pFendMsg->SendTxdDataFlag[1])
{
pFendMsg->SendTxdDataFlag[0] = TRUE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
}
gSendTxdDataFendIdx = 0;
}
break;
case 2: // 前置机 B 下发数据
2 years ago
if(pFendMsg->SendTxdDataFlag[1] == 0)
{
pFendMsg->SendTxdDataFlag[0] = FALSE;
PingData.dwStatus += 0x20;
}
else
{
if(pFendMsg->SendTxdDataFlag[0]
&& pFendMsg->SendTxdDataFlag[1])
{
pFendMsg->SendTxdDataFlag[0] = TRUE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
}
gSendTxdDataFendIdx = 0;
}
break;
}
servaddr = &UdpPing.SerAddr;
memset((char *)servaddr, 0, sizeof(struct sockaddr_in));
servaddr->sin_family = AF_INET;
servaddr->sin_addr.s_addr = htonl(pFendMsg->BroadCastAddr[i]);
if(0 == servaddr->sin_addr.s_addr)
{
continue;
}
//sprintf(szDbg, "Txd[%d]=%d, wNodeId=%d, inetAddr=%08x, inetMask=%08x, dwStatus=%08x\n",
// pFendMsg->FendIdx, pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx],
// PingData.wNodeID, PingData.inetAddr, PingData.inetMask, PingData.dwStatus);
//DebugPrint(szDbg);
// 字节顺序转换
2 years ago
//PingData.wNodeID = SequenceHostToRtuWord(PingData.wNodeID);
PingData.inetMask = SequenceHostToRtuDWord(PingData.inetMask);
PingData.inetAddr = SequenceHostToRtuDWord(PingData.inetAddr);
PingData.dwStatus = SequenceHostToRtuDWord(PingData.dwStatus);
//sprintf(szDbg, "Send dwStatus(change)=%02x", PingData.dwStatus);
//DebugPrint(szDbg);
servaddr->sin_port = htons(gUdpPingWritePort);
sendlen = sendto(UdpPing.sSocket[i], (char*)&PingData, sizeof(PINGINFORMATION), 0,
(struct sockaddr *)servaddr, sizeof(struct sockaddr_in));
//sprintf(szDbg, "sendto([%d] %08x:%d) <ip=%08x>",
//i, pFendMsg->BroadCastAddr[i], gUdpPingWritePort, pFendMsg->HostIpAddr[i]);
//DebugPrint(szDbg);
servaddr->sin_port = htons(gUdpPingReadPort);
sendlen = sendto(UdpPing.sSocket[i], (char*)&PingData, sizeof(PINGINFORMATION), 0,
(struct sockaddr *)servaddr, sizeof(struct sockaddr_in));
//sprintf(szDbg, "sendto([%d] %08x:%d) <ip=%08x>\n",
//i, pFendMsg->BroadCastAddr[i], gUdpPingReadPort, pFendMsg->HostIpAddr[i]);
//DebugPrint(szDbg);
}
//DebugPrint("UdpPingSendData End.");
}
void UdpPingSendDataP2P(void)
{
//char szDbg[256];
static int cnt = 0;
int i, j, sendlen;
struct sockaddr_in *servaddr;
PINGINFORMATION PingData;
// wen 2002.07.11
BOOL bSendFlag = FALSE;
TCP_LINK_DEF *pHostLink;
FEND_DEF *pFendMsg;
SIO_PARAM_DEF *pSioParam;
cnt++;
if((cnt * TIMER_CNT) < 1000)
{
return;
}
cnt = 0;
// 获取全局变量,通过函数调用
2 years ago
pHostLink = GetHostLinkPtr();
pFendMsg = GetFendMsgPtr();
//if(pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] == TRUE)
//{
// sprintf(szDbg, "FendIdx=%d is Txd Fend.", pFendMsg->FendIdx);
// DebugPrint(szDbg);
//}
memmove((char*)PingData.barrRandom, PINGRANDOM, MAX_RANDOM);
if(pFendMsg->FendIdx == 0)
{
strcpy((char*)PingData.szNodeName, "FENDA");
}
else
{
strcpy((char*)PingData.szNodeName, "FENDB");
}
PingData.bNodeType = FEND_TYPE;
PingData.wNodeID = pFendMsg->FendIdx;
PingData.inetMask = pFendMsg->HostIpAddr[0];
PingData.inetAddr = pFendMsg->AllIpAddr[0];
PingData.dwStatus = 0;
if(gPingWaitCnt < MAX_DELAYTIME)
{
gPingWaitCnt++;
}
//sprintf(szDbg, "WaitCnt=%d, Txd[0]=%d, Txd[1]=%d, Exist[0]=%d, Exist[1]=%d",
// gPingWaitCnt, pFendMsg->SendTxdDataFlag[0], pFendMsg->SendTxdDataFlag[1],
// pFendMsg->FendExistFlag[0], pFendMsg->FendExistFlag[1]);
//DebugPrint(szDbg);
if(gPingWaitCnt == 5)
{
if((pFendMsg->SendTxdDataFlag[0] == 0)
&& (pFendMsg->SendTxdDataFlag[1] == 0))
{
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.04.22 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
2 years ago
//pFendMsg->SendTxdDataFlag[0] = FALSE;
//pFendMsg->SendTxdDataFlag[1] = FALSE;
//pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
//=======================================================================
if(pFendMsg->iPortMask)
{
pSioParam = GetSioParamPtr();
for(i=0; i<DEFAULT_MAX_PORT_NUM; i++)
{
if(pFendMsg->iPortMask & (0x00000001 << i))
{
if(pSioParam[i].Status)
{
break;
}
}
}
}
else
{
i = DEFAULT_MAX_PORT_NUM;
}
if(i >= DEFAULT_MAX_PORT_NUM)
{
pFendMsg->SendTxdDataFlag[0] = FALSE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
}
if((gSendTxdDataFendIdx == 0) && (gPingWaitCnt > 10))
{
if((pFendMsg->SendTxdDataFlag[0] == 0)
&& (pFendMsg->SendTxdDataFlag[1] == 0))
{
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.04.22 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
2 years ago
//pFendMsg->SendTxdDataFlag[0] = FALSE;
//pFendMsg->SendTxdDataFlag[1] = FALSE;
//pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
//=======================================================================
if(pFendMsg->iPortMask)
{
pSioParam = GetSioParamPtr();
for(i=0; i<DEFAULT_MAX_PORT_NUM; i++)
{
if(pFendMsg->iPortMask & (0x00000001 << i))
{
if(pSioParam[i].Status)
{
break;
}
}
}
}
else
{
i = DEFAULT_MAX_PORT_NUM;
}
if(i >= DEFAULT_MAX_PORT_NUM)
{
pFendMsg->SendTxdDataFlag[0] = FALSE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
}
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
}
// wen 2006.04.29 在uclinux下发送数据给自己无法接收的到。始终认为自己是存在的。
2 years ago
#ifdef OS_LINUX
pFendMsg->FendExistFlag[pFendMsg->FendIdx] = TRUE;
pFendMsg->FendExistCnt[pFendMsg->FendIdx] = 0;
#endif
if(pFendMsg->FendExistFlag[0] == FALSE)
{
pFendMsg->SendTxdDataFlag[0] = FALSE;
}
if(pFendMsg->FendExistFlag[1] == FALSE)
{
pFendMsg->SendTxdDataFlag[1] = FALSE;
}
// wen 2002.11.25 连接服务器慢的系统会出现切换不成功
2 years ago
/*
switch(pFendMsg->LinkStatus[1]*2 + pFendMsg->LinkStatus[0])
{
case 0x01:
pFendMsg->SendTxdDataFlag[0] = TRUE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
break;
case 0x02:
pFendMsg->SendTxdDataFlag[0] = FALSE;
pFendMsg->SendTxdDataFlag[1] = TRUE;
break;
}
*/
}
//DebugPrint("UdpPingSendDataP2P Begin...");
// 字节顺序转换
2 years ago
PingData.wNodeID = SequenceHostToRtuWord(PingData.wNodeID);
for(i = 0; i < MAX_ADDR; i++)
{
if(INVALID_SOCKET == UdpPing.sSocket[i])
{
continue;
}
PingData.inetMask = pFendMsg->HostIpAddr[i];
PingData.inetAddr = pFendMsg->AllIpAddr[i];
PingData.dwStatus = (pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] ? 4 : 0)
+ (pHostLink[1].InitOk ? 2 : 0) + (pHostLink[0].InitOk ? 1 : 0) + 0x30000;
switch(gSendTxdDataFendIdx)
{
case 1: // 前置机 A 下发数据
2 years ago
if(pFendMsg->SendTxdDataFlag[0] == 0)
{
pFendMsg->SendTxdDataFlag[1] = FALSE;
PingData.dwStatus += 0x10;
}
else
{
if(pFendMsg->SendTxdDataFlag[0]
&& pFendMsg->SendTxdDataFlag[1])
{
pFendMsg->SendTxdDataFlag[0] = TRUE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
}
gSendTxdDataFendIdx = 0;
}
break;
case 2: // 前置机 B 下发数据
2 years ago
if(pFendMsg->SendTxdDataFlag[1] == 0)
{
pFendMsg->SendTxdDataFlag[0] = FALSE;
PingData.dwStatus += 0x20;
}
else
{
if(pFendMsg->SendTxdDataFlag[0]
&& pFendMsg->SendTxdDataFlag[1])
{
pFendMsg->SendTxdDataFlag[0] = TRUE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
}
gSendTxdDataFendIdx = 0;
}
break;
}
servaddr = &UdpPing.SerAddr;
memset((char *)servaddr, 0, sizeof(struct sockaddr_in));
servaddr->sin_family = AF_INET;
//servaddr->sin_addr.s_addr = htonl(pFendMsg->SetTcpIpAddr[2*i]);
// 字节顺序转换
2 years ago
//PingData.wNodeID = SequenceHostToRtuWord(PingData.wNodeID);
PingData.inetMask = SequenceHostToRtuDWord(PingData.inetMask);
PingData.inetAddr = SequenceHostToRtuDWord(PingData.inetAddr);
PingData.dwStatus = SequenceHostToRtuDWord(PingData.dwStatus);
// 点对点发送给前置机
2 years ago
for(j=0; j<MAX_FEND; j++)
{
// wen 2006.04.29 在uclinux下发送数据给自己无法接收的到。所以不发送数据给自己。
2 years ago
#ifdef OS_LINUX
if(j == pFendMsg->FendIdx)
{
continue;
}
#endif
if(strlen(pFendMsg->SetTcpIpAddr[MAX_FEND*j+i]) > 0)
{
//sprintf(szDbg, "FEND_%d: Txd[%d]=%d, wNodeId=%d, inetAddr=%08x, inetMask=%08x, dwStatus=%08x\n",
// j+1, pFendMsg->FendIdx, pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx],
// PingData.wNodeID, PingData.inetAddr, PingData.inetMask, PingData.dwStatus);
//DebugPrint(szDbg);
//sprintf(szDbg, "Send dwStatus(change)=%02x", PingData.dwStatus);
//DebugPrint(szDbg);
servaddr->sin_addr.s_addr = inet_addr((char *)pFendMsg->SetTcpIpAddr[MAX_FEND*j+i]);
//DebugPrint((char *)pFendMsg->SetTcpIpAddr[MAX_FEND*j+i]);
servaddr->sin_port = htons(gUdpPingReadPort);
sendlen = sendto(UdpPing.sSocket[i], (char*)&PingData, sizeof(PINGINFORMATION), 0,
(struct sockaddr *)servaddr, sizeof(struct sockaddr_in));
//sprintf(szDbg, "sendto([%d] %08x:%d) <ip=%08x>\n",
//i, pFendMsg->BroadCastAddr[i], gUdpPingReadPort, pFendMsg->HostIpAddr[i]);
//DebugPrint(szDbg);
}
}
// 点对点发送给服务器
2 years ago
for(j=0; j<MAX_HOST; j++)
{
if(strlen((char *)pHostLink[j].TcpIpAddr[i]) > 0)
{
//sprintf(szDbg, "HOST_%d: Txd[%d]=%d, wNodeId=%d, inetAddr=%08x, inetMask=%08x, dwStatus=%08x\n",
// j+1, pFendMsg->FendIdx, pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx],
// PingData.wNodeID, PingData.inetAddr, PingData.inetMask, PingData.dwStatus);
//DebugPrint(szDbg);
servaddr->sin_addr.s_addr = inet_addr((char *)pHostLink[j].TcpIpAddr[i]);
servaddr->sin_port = htons(gUdpPingWritePort);
sendlen = sendto(UdpPing.sSocket[i], (char*)&PingData, sizeof(PINGINFORMATION), 0,
(struct sockaddr *)servaddr, sizeof(struct sockaddr_in));
}
}
}
//DebugPrint("UdpPingSendDataP2P End.");
}
void UdpPingReaddata(void)
{
fd_set set;
struct timeval outtime;
struct sockaddr_in src_servaddr;
int rlen, i, j, k;
short msglen;
u_char msgdata[MAX_RTU_MSG_SIZE];
PINGINFORMATION *pingmsg;
char revip[32];
char szbuf[128];
static int dflag = 0;
// wen 2002.11.11 前置机为备用机B时主机退出无法进行切换
2 years ago
static int recvtimeout = 0;
TCP_LINK_DEF *pHostLink;
FEND_DEF *pFendMsg;
SIO_PARAM_DEF *pSioParam;
// 获取全局变量,通过函数调用
2 years ago
pHostLink = GetHostLinkPtr();
pFendMsg = GetFendMsgPtr();
//for(i = 0; i < MAX_ADDR; i++)
{
memset((char*)&outtime, 0, sizeof(struct timeval));
memset((char*)&src_servaddr, 0, sizeof(src_servaddr));
FD_ZERO(&set);
FD_SET(UdpPing.rSocket, &set);
if(UdpPing.rSocket == INVALID_SOCKET)
{
return;
}
for(; ;)
{
rlen = select(UdpPing.rSocket+1, &set, NULL, NULL, &outtime);
if(rlen < 1)
{
break;
}
rlen = sizeof(struct sockaddr_in);
msglen = recvfrom(UdpPing.rSocket, (char*)msgdata, MAX_RTU_MSG_SIZE,
0, (struct sockaddr*)&src_servaddr, &rlen);
if(msglen == SOCKET_ERROR)
{
break;
}
for(j = 0; j < msglen; j += sizeof(PINGINFORMATION))
{
pingmsg = (PINGINFORMATION*)msgdata;
//if(!CmpnString((char*)pingmsg->barrRandom, PINGRANDOM, MAX_RANDOM-1))
// continue;
// 字节顺序转换
2 years ago
pingmsg->wNodeID = SequenceRtuToHostWord(pingmsg->wNodeID);
pingmsg->inetAddr = SequenceRtuToHostDWord(pingmsg->inetAddr);
pingmsg->inetMask = SequenceRtuToHostDWord(pingmsg->inetMask);
pingmsg->dwStatus = SequenceRtuToHostDWord(pingmsg->dwStatus);
//sprintf(szbuf, "recv: wNodeId=%d, inetAddr=%08x, inetMask=%08x, dwStatus=%08x",
// pingmsg->wNodeID, pingmsg->inetAddr, pingmsg->inetMask, pingmsg->dwStatus);
//DebugPrint(szbuf);
switch(pingmsg->bNodeType)
{
case MMI_TYPE:
break;
case FEND_TYPE:
/* test
if(gtestread == 0)
{
// 前置机a
2 years ago
if(pingmsg->wNodeID == 0)
{
DebugPrint("屏蔽前置机a的ping包");
2 years ago
break;
}
}*/
// wen 2002.11.11 前置机为备用机B时主机退出无法进行切换
// 每一个ping 包 一秒钟发送一次
2 years ago
if(!pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx])
{
if(recvtimeout < 6)
{
recvtimeout++;
}
else
{
recvtimeout = 0;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.04.22 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
2 years ago
//pFendMsg->SendTxdDataFlag[(pFendMsg->FendIdx+1)%MAX_ADDR] = FALSE;
//pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
//=======================================================================
if(pFendMsg->iPortMask)
{
pSioParam = GetSioParamPtr();
for(i=0; i<DEFAULT_MAX_PORT_NUM; i++)
{
if(pFendMsg->iPortMask & (0x00000001 << i))
{
if(pSioParam[i].Status)
{
break;
}
}
}
}
else
{
i = DEFAULT_MAX_PORT_NUM;
}
if(i >= DEFAULT_MAX_PORT_NUM)
{
pFendMsg->SendTxdDataFlag[(pFendMsg->FendIdx+1)%MAX_ADDR] = FALSE;
pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = TRUE;
}
}
}
for(k = 0; k < MAX_FEND*MAX_ADDR; k++)
{
if((k / MAX_ADDR) == pFendMsg->FendIdx)
{
if(inet_addr((char*)pFendMsg->TcpIpAddr[k % MAX_ADDR]) != src_servaddr.sin_addr.s_addr)
continue;
}
else
{
if(inet_addr((char*)pFendMsg->SetTcpIpAddr[k]) != src_servaddr.sin_addr.s_addr)
{
continue;
}
// wen 2002.11.11 前置机为备用机B时主机退出无法进行切换
2 years ago
recvtimeout = 0;
}
if((k / MAX_ADDR) != pingmsg->wNodeID)
continue;
pFendMsg->FendExistFlag[pingmsg->wNodeID] = TRUE;
pFendMsg->FendExistCnt[pingmsg->wNodeID] = 0;
pFendMsg->LinkStatus[pingmsg->wNodeID] = (pingmsg->dwStatus & 0x03) ? 1 : 0;
if(pFendMsg->LinkStatus[pingmsg->wNodeID])
pFendMsg->LinkCnt[pingmsg->wNodeID] = 0;
pFendMsg->SendTxdDataFlag[pingmsg->wNodeID] = (pingmsg->dwStatus & 0x04) ? TRUE : FALSE;
switch(pingmsg->dwStatus & 0x30)
{
case 0x10:
pFendMsg->SendTxdDataFlag[0] = TRUE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
break;
case 0x20:
pFendMsg->SendTxdDataFlag[0] = FALSE;
pFendMsg->SendTxdDataFlag[1] = TRUE;
break;
// wen 2002.04.05
default:
if(pFendMsg->SendTxdDataFlag[0] & pFendMsg->SendTxdDataFlag[1])
{
pFendMsg->SendTxdDataFlag[0] = TRUE;
pFendMsg->SendTxdDataFlag[1] = FALSE;
}
break;
}
// wen 2006.04.29 多余的指令,这种情况永远不会发生,上面已经消除了这种情况
2 years ago
//if(pFendMsg->SendTxdDataFlag[0] && pFendMsg->SendTxdDataFlag[1])
//{
// pFendMsg->SendTxdDataFlag[1] = FALSE;
//}
break;
}
break;
case HOST_TYPE:
for(k = 0; k < MAX_HOST * MAX_ADDR; k++)
{
strcpy((char*)revip, inet_ntoa(*(struct in_addr*)&src_servaddr.sin_addr.s_addr));
if(inet_addr((char*)pHostLink[k / MAX_ADDR].TcpIpAddr[k % MAX_ADDR]) != src_servaddr.sin_addr.s_addr)
continue;
if((k / MAX_ADDR) != pingmsg->wNodeID)
continue;
pHostLink[pingmsg->wNodeID].RevHostStatusMsg = TRUE;
pHostLink[pingmsg->wNodeID].VersionFalgByte = (u_char)(HIWORD(pingmsg->dwStatus) >> 8);
pHostLink[pingmsg->wNodeID].Status = (u_char)(LOWORD(pingmsg->dwStatus) - 1);
if(pHostLink[pingmsg->wNodeID].InitOk == TRUE)
pHostLink[pingmsg->wNodeID].StatusCnt = 0;
break;
}
if((pHostLink[0].Status == 0) && (pHostLink[1].Status == 0))
{
if(dflag == 0)
{
sprintf(szbuf, "接收服务器状态为双主机状态错误!!! 当前处理服务器 %c 状态包。", pingmsg->wNodeID + 'A');
2 years ago
DebugPrint((char*)szbuf);
}
dflag = 1;
}
else
{
if(dflag)
{
if(pHostLink[0].Status == 0)
{
sprintf(szbuf, "接收服务器状态 A 服务器为主机!!!");
2 years ago
DebugPrint((char*)szbuf);
}
if(pHostLink[1].Status == 0)
{
sprintf(szbuf, "接收服务器状态 B 服务器为主机!!!");
2 years ago
DebugPrint((char*)szbuf);
}
}
dflag = 0;
}
//sprintf(szbuf, "pHostLink[0].Status=%d, pHostLink[1].Status=%d\n",
// pHostLink[0].Status, pHostLink[1].Status);
//DebugPrint(szbuf);
break;
}
}
}
}
}
void UdpPingClose(void)
{
int i;
for(i = 0; i < MAX_ADDR; i++)
{
if(UdpPing.sSocket[i] == INVALID_SOCKET)
{
continue;
}
CloseNetSocket(UdpPing.sSocket[i]);
UdpPing.sSocket[i] = INVALID_SOCKET;
}
if(UdpPing.rSocket != INVALID_SOCKET)
{
CloseNetSocket(UdpPing.rSocket);
}
UdpPing.rSocket = INVALID_SOCKET;
gUdpPingInitOk = FALSE;
}
void UdpPingSwitch(void)
{
int i;
FEND_DEF *pFendMsg;
// 获取全局变量,通过函数调用
2 years ago
pFendMsg = GetFendMsgPtr();
for(i=0; i<MAX_FEND; i++)
{
pFendMsg->FendExistFlag[i] = FALSE;
pFendMsg->FendExistCnt[i] = 0;
pFendMsg->LinkStatus[i] = FALSE;
pFendMsg->LinkCnt[i] = 0;
}
if(pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] == TRUE)
{
pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx] = FALSE;
if(pFendMsg->FendIdx == 0)
{
gSendTxdDataFendIdx = 2;
}
else
{
gSendTxdDataFendIdx = 1;
}
}
else
{
if(pFendMsg->FendIdx == 0)
{
gSendTxdDataFendIdx = 1;
}
else
{
gSendTxdDataFendIdx = 2;
}
}
}