/************************************************************************************ * * 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; iiPortMask & (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; iiPortMask & (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) ", //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) \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; iiPortMask & (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; iiPortMask & (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; jFendIdx) { 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) \n", //i, pFendMsg->BroadCastAddr[i], gUdpPingReadPort, pFendMsg->HostIpAddr[i]); //DebugPrint(szDbg); } } // 点对点发送给服务器 for(j=0; j 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; iiPortMask & (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; iFendExistFlag[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; } } }