📄 mbtcp.c
字号:
memset(RecvBuff, 0, 5); SaveHMICommand(RecvBuff, nRecv); SendBuff[5] = 6 ; memcpy(SendBuff+7, RecvBuff+7, 5); nSend = SendBuff[5]+6; CONN_SendBuff(MBTCP_B_ClientSocket[i].Socket_fd, SendBuff, nSend); break; default : break; } } } else if(PreRead==0) //客户端断开了连接 { MBTCP_BFlag --; FD_CLR(MBTCP_B_ClientSocket[i].Socket_fd, &MBTCP_Sockset); close(MBTCP_B_ClientSocket[i].Socket_fd); MBTCP_Conn_Clear(1, i); //printf("Disconnect i=%d \n",i); } else { getsockopt(MBTCP_B_ClientSocket[i].Socket_fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); } } } } MBTCP_Add_Socket(&MBTCP_Sockset, MBTCP_ListenSocket, MBTCP_A_ClientSocket, MBTCP_B_ClientSocket); }}int Recv_MBTCP_Command(SOCKET Client_Fd,unsigned char *NetRecvBuff){ int k,len = 0,nRecv = 0; unsigned char TempBuff[256]; /* request: 00 00 00 00 00 06 后续字节个数 09 子站ID 03 功能码 00 00 起始地址 00 01 读取个数 response: 00 00 00 00 00 06 09 03 00 00 00 01 response: 00 00 00 00 00 05 09 03 02 12 34 */ for(k=0;k<256;k++) { len=recv(Client_Fd,TempBuff,1,0);//每次读取一个字节 if (len>0) { memcpy( (NetRecvBuff+nRecv), TempBuff, len) ; nRecv+=len; if(nRecv>=*(NetRecvBuff+5)+6) { nRecv=*(NetRecvBuff+5)+6; return nRecv; } } } return 0;}void MBTCP_Add_Socket(fd_set *sockset,SOCKET *ListenSockfd,CONNECTION *A_ClientSockfd, CONNECTION *B_ClientSockfd){ int i; FD_ZERO(sockset); for(i=0; i<2; i++) { FD_SET(ListenSockfd[i],sockset); } for(i=0; i<MBTCP_Client_Num; i++) { if(A_ClientSockfd[i].inUse) { FD_SET(A_ClientSockfd[i].Socket_fd,sockset); } if(B_ClientSockfd[i].inUse) { FD_SET(B_ClientSockfd[i].Socket_fd,sockset); } }}int GetMBTCPFreeConnect(int NetGroup){ int i; switch(NetGroup) { case 0: for (i=0 ; i < MBTCP_Client_Num ; i++) { if (MBTCP_A_ClientSocket[i].inUse == 0) { return i; } } break; case 1: for (i=0 ; i < MBTCP_Client_Num ; i++) { if (MBTCP_B_ClientSocket[i].inUse == 0) { return i; } } break; } return -1;}struct sockaddr_in serv_addr;void MBTCP_Client(void) { struct linger lingero; int optval, optlen = sizeof(int); int Socket_fd,nGroup = 0; int nRecv, nSend, PreRead, MbDebPort = 9; int nLen, iRead, IsConnected = 0; unsigned char FunCode = 0; unsigned char SendBuff[256],RecvBuff[256]; fd_set sockset; struct timeval TimeOut; int CurrentIP_ISIP1 = 1 ; int ServerPort = 502, IP_LEN = 32 ; char ServerIP[32], IP1[32], IP2[32]; unsigned char sub_UnitID = LOBYTE(MyFlashBuff[ModbusTCP]); sprintf(IP1, "%d.%d.%d.%d", HIBYTE( MyFlashBuff[ModbusTCP+1]), LOBYTE(MyFlashBuff[ModbusTCP+1]), HIBYTE(MyFlashBuff[ModbusTCP+2]), LOBYTE(MyFlashBuff[ModbusTCP+2]) ); MBTCP_YC_Addr = MyFlashBuff[ModbusTCP+3]; MBTCP_YX_Addr = MyFlashBuff[ModbusTCP+4]; sprintf(IP2, "%d.%d.%d.%d", HIBYTE(MyFlashBuff[ModbusTCP+5]), LOBYTE(MyFlashBuff[ModbusTCP+5]), HIBYTE(MyFlashBuff[ModbusTCP+6]), LOBYTE(MyFlashBuff[ModbusTCP+6]) ); memcpy(ServerIP, IP1, IP_LEN); //首先把要连接的IP设定为A网PLC的IP地址 if( nTransYc%Every_YC_Frame_Num ) nGroup = nTransYc/Every_YC_Frame_Num + 2 ; else nGroup = nTransYc/Every_YC_Frame_Num + 1 ; //printf("IP1: %s\n", IP1); printf("IP2: %s\n", IP2); while(1) { if( IsConnected == 0 ) //如果没有与PLC(ModbusTCP协议)建立连接 { CurrentIP_ISIP1 = !CurrentIP_ISIP1; //保证每次中断后连接不同的IP,达到主备冗余的目的 if( CurrentIP_ISIP1 ) memcpy( ServerIP, IP2, IP_LEN ); else memcpy( ServerIP, IP1, IP_LEN ); //printf("ServerIP: %s\n", ServerIP); Socket_fd = Init_Socket(ServerIP, ServerPort); //必须每次初始化Socket if( Socket_fd > 0 ) { getsockopt(Socket_fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); if( connect(Socket_fd, ( struct sockaddr *)&serv_addr, sizeof( serv_addr))<0 ) { fcntl(Socket_fd, F_SETFL, fcntl(Socket_fd, F_GETFL, 0) | O_NONBLOCK); FD_CLR(Socket_fd,&sockset); close(Socket_fd); SYS_Delay(200); } else { getsockopt(Socket_fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); optlen = sizeof(lingero); lingero.l_onoff=1; lingero.l_linger=1; setsockopt(Socket_fd, SOL_SOCKET, SO_LINGER, &lingero, optlen); IsConnected = 1; } } else { getsockopt(Socket_fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); SYS_Delay(200); } } else //已经与PLC建立连接,对PLC轮询遥信遥测数据或者执行HMI的命令 { Add_Set(&sockset, &Socket_fd); nLen = Pack_MBTCP_SendFrame(SendBuff, sub_UnitID, FunCode); getsockopt(Socket_fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); nSend = CONN_SendBuff(Socket_fd, SendBuff, nLen); if( nSend != nLen ) { getsockopt(Socket_fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); FD_CLR(Socket_fd,&sockset); close(Socket_fd); IsConnected = 0; } else { PrintDebugInfo(MbDebPort, Send_Data, SendBuff, nSend); } TimeOut.tv_sec = 0; TimeOut.tv_usec = 500000; if(select(Socket_fd+1, &sockset, NULL, NULL,&TimeOut) != 0) { if(FD_ISSET(Socket_fd, &sockset)) { getsockopt(Socket_fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); PreRead = recv(Socket_fd, RecvBuff, sizeof(RecvBuff), MSG_PEEK);//查看缓冲区,不清数据 if( PreRead > 0 ) { nRecv = Read_MBTCP_Recv(Socket_fd, sub_UnitID, RecvBuff);//读取缓冲区数据,看是否有正确报文接收 if(nRecv>0) { PrintDebugInfo(MbDebPort, Recv_Data, RecvBuff, nRecv); //ProcessPLCRecvData(RecvBuff, nRecv); 写PLC成功后,PLC返回的确认报文,没用 } SYS_Delay(500); } else if(PreRead==0) { getsockopt(Socket_fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); FD_CLR(Socket_fd, &sockset); close(Socket_fd); IsConnected = 0; } else { getsockopt(Socket_fd, SOL_SOCKET, SO_ERROR, &optval, &optlen); } } } FunCode = (FunCode+1)%nGroup; } }}void Add_Set(fd_set *sockset, int *Socket_fd){ FD_ZERO(sockset); FD_SET(*Socket_fd, sockset); }int Init_Socket(char *SERV_HOST_ADDR,unsigned int SERV_TCP_PORT) // Return Socket_fd if successful, else 0{ int Sock_fd; bzero((char*)&serv_addr, sizeof(serv_addr)); serv_addr.sin_family =AF_INET; serv_addr.sin_addr.s_addr =inet_addr( SERV_HOST_ADDR); serv_addr.sin_port = htons(SERV_TCP_PORT); if((Sock_fd = socket(AF_INET,SOCK_STREAM,0))<0) { printf( "Create Socket Error\n"); return 0; } return Sock_fd;}int Pack_MBTCP_SendFrame(unsigned char *pFrame, unsigned char PLC_UnitID, unsigned char sOrder){ int i,m,ret=0,nBytes,nGroup; unsigned short YC_BeginAddr; unsigned char BytesYX[256]; /* BYTE0~4 00 00 00 00 00 BYTE5 0B 后续字节个数 BYTE6 09 子站ID BYTE7 10 功能码 BYTE8~9 00 00 起始地址 BYTE10~11 00 02 写寄存器个数 BYTE12 04 写字节个数 BYTE13~14 02 41 第一个数据 BYTE15~16 12 21 第二个数据*/ memset(pFrame, 0, 5); pFrame[6] = PLC_UnitID; pFrame[7] = 0x10; if(sOrder==0)//向PLC转发遥信数据 { pFrame[8] = HIBYTE(MBTCP_YX_Addr) ; pFrame[9] = LOBYTE(MBTCP_YX_Addr) ; pFrame[10] = 0; nBytes = BitToByte(BytesYX, MemYXBuff, nTransYx); if(nBytes%2) pFrame[12] = nBytes+3; else pFrame[12] = nBytes+2; pFrame[11] = pFrame[12]/2 ; pFrame[13] = 0xFF ; pFrame[14] = 0xFF ; for(i=0;i<pFrame[11]-1;i++) { pFrame[15+2*i] = BytesYX[2*i+1]; pFrame[16+2*i] = BytesYX[2*i]; } } else//向PLC转发遥测数据 { if(nTransYc%Every_YC_Frame_Num) nGroup = nTransYc/Every_YC_Frame_Num+2; else nGroup = nTransYc/Every_YC_Frame_Num+1; YC_BeginAddr = (sOrder-1)*Every_YC_Frame_Num+MBTCP_YC_Addr; pFrame[8] = HIBYTE(YC_BeginAddr) ; pFrame[9] = LOBYTE(YC_BeginAddr) ; pFrame[10] = 0; if(sOrder==nGroup-1)//最后一组遥测 { pFrame[11] = nTransYc - (sOrder-1)*Every_YC_Frame_Num ; } else { pFrame[11] = Every_YC_Frame_Num ; } pFrame[12] = pFrame[11]*2; memcpy(pFrame+13, MemYCBuff+(sOrder-1)*Every_YC_Frame_Num*2, pFrame[12]) ; } pFrame[5] = pFrame[12]+7 ; return pFrame[5]+6;}int Read_MBTCP_Recv(int Client_Fd,unsigned char SubID,unsigned char *NetRecvBuff){ //request: 00 00 00 00 00 06 09 03 00 04 00 01 //response: 00 00 00 00 00 05 09 03 02 00 05 int nRecv = 0; unsigned char TempBuff[256]; nRecv = recv(Client_Fd,TempBuff, sizeof(TempBuff), 0); if (nRecv>0) { if ((*(TempBuff+6)==SubID)&&(nRecv >= *(TempBuff+5)+6)) { nRecv = *(TempBuff+5)+6; memcpy( NetRecvBuff, TempBuff, nRecv ) ; return nRecv; } } return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -