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++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

/************************************************************************************
*
* 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地址可重用。
//***************************************************************
#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; // 是否广播方式发送数据报
#endif
int timeout = 1000; // 超时
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);
//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设置为非阻塞模式
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包
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 服务器和前置机共处一台机器中,会出现绑定失败。套接字地址被使用
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;
// 获取全局变量,通过函数调用
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 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
//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 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
//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 连接服务器慢的系统会出现切换不成功
/*
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...");
// 字节顺序转换
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 下发数据
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 下发数据
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);
// 字节顺序转换
//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;
// 获取全局变量,通过函数调用
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 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
//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 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
//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下发送数据给自己无法接收的到。始终认为自己是存在的。
#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 连接服务器慢的系统会出现切换不成功
/*
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...");
// 字节顺序转换
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 下发数据
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 下发数据
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]);
// 字节顺序转换
//PingData.wNodeID = SequenceHostToRtuWord(PingData.wNodeID);
PingData.inetMask = SequenceHostToRtuDWord(PingData.inetMask);
PingData.inetAddr = SequenceHostToRtuDWord(PingData.inetAddr);
PingData.dwStatus = SequenceHostToRtuDWord(PingData.dwStatus);
// 点对点发送给前置机
for(j=0; j<MAX_FEND; j++)
{
// wen 2006.04.29 在uclinux下发送数据给自己无法接收的到。所以不发送数据给自己。
#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);
}
}
// 点对点发送给服务器
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时主机退出无法进行切换
static int recvtimeout = 0;
TCP_LINK_DEF *pHostLink;
FEND_DEF *pFendMsg;
SIO_PARAM_DEF *pSioParam;
// 获取全局变量,通过函数调用
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;
// 字节顺序转换
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
if(pingmsg->wNodeID == 0)
{
DebugPrint("屏蔽前置机a的ping包");
break;
}
}*/
// wen 2002.11.11 前置机为备用机B时主机退出无法进行切换
// 每一个ping 包 一秒钟发送一次
if(!pFendMsg->SendTxdDataFlag[pFendMsg->FendIdx])
{
if(recvtimeout < 6)
{
recvtimeout++;
}
else
{
recvtimeout = 0;
//+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
// wen 2006.04.22 主备切换时,判断的端口通讯状态屏蔽字(按位屏蔽)
//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时主机退出无法进行切换
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 多余的指令,这种情况永远不会发生,上面已经消除了这种情况
//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');
DebugPrint((char*)szbuf);
}
dflag = 1;
}
else
{
if(dflag)
{
if(pHostLink[0].Status == 0)
{
sprintf(szbuf, "接收服务器状态 A 服务器为主机!!!");
DebugPrint((char*)szbuf);
}
if(pHostLink[1].Status == 0)
{
sprintf(szbuf, "接收服务器状态 B 服务器为主机!!!");
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;
// 获取全局变量,通过函数调用
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;
}
}
}