nrlan103def.cpp
来自「电力故障信息采集,主要是针对南自的保护装置,这个程序用在Linux操作系统下」· C++ 代码 · 共 324 行
CPP
324 行
#include "NRLan103def.h"NRLAN103::CommMannager::CommMannager(){ connected=false; threadId=0; m_sockfd=-1; debugLevel=5; pthread_mutex_init(&fastMutex,NULL); lastImpuls=-1; lastSend=-1; rcvCount=-1;}NRLAN103::CommMannager::~CommMannager(){ //if(threadId!=0)pthread_kill(threadId,0);// terminate(); if(m_sockfd!=-1) close(m_sockfd); pthread_mutex_destroy(&fastMutex);}int NRLAN103::CommMannager::CommThread(){ #ifdef NRLAN_DEBUG printf("entering CommMannager::CommThread()\n"); #endif pthread_mutex_lock(&fastMutex); threadId=pthread_self();// sndQueue.clear();// rcvQueue.clear(); pthread_mutex_unlock(&fastMutex); //connect using tcp // int sockfd=socket(AF_INET,SOCK_STREAM,0); // if(sockfd==-1) // return -1; // struct sockaddr_in addr; // bzero(&addr,sizeof(struct sockaddr_in)); // addr.sin_family=AF_INET; // addr.sin_addr.s_addr=inet_addr(theirAddr.c_str()); // addr.sin_port=htons(m_port); // int ret=connect(sockfd,(sockaddr*)&addr,sizeof(sockaddr_in)); // if(ret==-1) // { // char msg[200]; // bzero(msg,200); // sprintf(msg,"NRLAN103::CommMannager::CommThread:\n\tcan not connect to \ // %s:%d;\n\tThread exit with -1\n",theirAddr.c_str(),m_port); // printData(NULL,0,msg,1); // close(sockfd); // return -1; // } // m_sockfd=sockfd; //connect to host via pComm connected=true; //reset send count //impulsHead.wDataNumber=0x0000; /*check connection and time*/ if(!_pComm->IsConnected()) { connected=false; return -1; } #ifdef NRLAN_DEBUG printf("time \n\t%d\t%d\n",time(NULL),lastSend); #endif if(time(NULL)-lastSend>=10) { #ifdef NRLAN_DEBUG printf("will send impulse frame\n"); #endif send(0/*dummy*/); lastSend=time(NULL); } if(!sndQueue.empty()) { #ifdef NRLAN_DEBUG printf("will send normal frame\n"); #endif send(0/*dummy*/,true); } #ifdef NRLAN_DEBUG printf("will recv\n"); #endif receive(0/*dummy*/,rcvCount,lastImpuls); if(time(NULL)-lastImpuls>30) {/* close(sockfd); m_sockfd=-1;*/ pComm()->Close(); connected=false; threadId=0; } return 0;}bool NRLAN103::CommMannager::receive(int sockfd,int& count,time_t& lastImpuls){ if(sockfd==-1){}//return false; //else { unsigned char buff[1500]; unsigned char* inputPos=buff; int rcvBytes=0; struct timeval tv; bzero(&tv,sizeof(struct timeval)); tv.tv_usec=500*1000; fd_set readSet; FD_ZERO(&readSet); FD_SET(sockfd,&readSet); //select(sockfd+1,&readSet,NULL,NULL,&tv); if(!FD_ISSET(sockfd,&readSet)) { //return false; } //else { //for debug // sleep(5); int c=0; int single=0; single=pComm()->read(inputPos,1); if(single>0) c+=single; else { if(errno==ECONNRESET) {/* close(m_sockfd);*/ pComm()->Close(); m_sockfd=-1; connected=false; } perror(strerror(errno)); usleep(1000*1000); return false; } printData(buff,c,"NRLAN103::CommMannager\n\treceive",5); if(*inputPos==0x90) { single=pComm()->read(++inputPos,1); if(single>0) c+=single; else { if(errno==ECONNRESET) { this->pComm()->Close(); m_sockfd=-1; connected=false; } perror(strerror(errno)); usleep(1000*1000); return false; } printData(buff,c,"NRLAN103::CommMannager\n\treceive",5); if(*inputPos==0xEB) { single=pComm()->read(++inputPos,6); if(single>=6) c+=single; else { if(errno==ECONNRESET) { pComm()->Close(); m_sockfd=-1; connected=false; } perror(strerror(errno)); usleep(1000*1000); return false; } printData(buff,c,"NRLAN103::CommMannager\n\treceive",5); if(*(inputPos+4)==0x90&&*(inputPos+5)==0xEB) { inputPos+=6; int dataSize=*((DWORD*)(buff+2)); if(dataSize==0) return false; int actualRecv=0; int times=0; while(actualRecv<dataSize&×<20) { actualRecv+=pComm()->read(inputPos,dataSize-actualRecv); usleep(50*1000); times++; } //for debug: // printf("NRLAN103::CommMannager::receive:\n\treceive %d bytes:\n",actualRecv+8); // for(int i=0;i<actualRecv+8;i++) // { // printf("%02x ",buff[i]); // if((i+1)%16==0)printf("\n"); // } // printf("\n") printData(buff,actualRecv+8,"NRLAN103::CommMannager\n\treceive frame",5); if(dataSize==actualRecv) { //check recv count PackHead* head=(PackHead*)buff; int thisCount=head->wDataNumber; if(thisCount>count) { if(thisCount-count>10000) { return false; } } else { if(count-thisCount<45535) { return false; } } lastImpuls=time(NULL); count=thisCount; int asduSize=dataSize-(sizeof(PackHead)-8); if(asduSize>6) { ASDUbuff asdu; memcpy(asdu.buff,buff+sizeof(PackHead),asduSize);#ifdef NR_WAVE_DEBUG if(asdu.buff[0]==26) { dump((char*)asdu.buff,(char*)asdu.buff+asduSize,"asdu26 dump:"); } else if(asdu.buff[0]==30) { dump((char*)asdu.buff,(char*)asdu.buff+asduSize,"asdu30 dump:"); }#endif asdu.size=asduSize; pthread_mutex_lock(&fastMutex); rcvQueue.push_back(asdu); CByteArray array; array.SetSize(asduSize); memcpy(array.GetData(),buff+sizeof(PackHead),asduSize); pthread_mutex_unlock(&fastMutex); return true; } } } } } } } return false;}bool NRLAN103::CommMannager::send(int sockfd,bool isCmd){ impulsHead.wDataNumber++; BYTE sndBuff[1500]; memcpy(sndBuff,&impulsHead,sizeof(PackHead)); PackHead* hptr=(PackHead*)sndBuff; if(isCmd) { memcpy(sndBuff+sizeof(PackHead),&(sndQueue[0].buff),sndQueue[0].size); hptr->wLength=sizeof(PackHead)+sndQueue[0].size-8; sndQueue.pop_front(); } else { hptr->wDestinationAddr=0xFFFF; }/* ::send(sockfd,sndBuff,hptr->wLength+8,0);*/ #ifdef NRLAN_DEBUG printf("will send via pComm\n"); #endif pComm()->write(sndBuff,hptr->wLength+8); #ifdef NRLAN_DEBUG printf("send via pComm complete\n"); #endif printData(sndBuff,hptr->wLength+8,"CommMannager::send\n\tsend frame\n",5); return true;}bool NRLAN103::CommMannager::CommStart(const char* ipaddr, WORD port,BYTE addr,BYTE staAddr){ char msg[200]; bzero(msg,200); sprintf(msg,"NRLAN103::CommMannager::CommStart\n\tIPaddr: %s\tport: %d\tdevice addr: %02x\n",ipaddr,port,addr); printData(NULL,0,msg,1); theirAddr=ipaddr; m_port=port; impulsHead.wSourceAddr=0xFE00+staAddr; impulsHead.wDeviceState=0x50; impulsHead.wDestinationAddr=/*0xFF00+*/addr; //if(pthread_create(&threadId,NULL,/*CommThread*/boost::ptr_fun(threadFunc),NULL)==0)return true; //start(); return connected;}bool NRLAN103::CommMannager::CommSend(const ASDUbuff& asdu){ pthread_mutex_lock(&fastMutex); sndQueue.push_back(asdu); pthread_mutex_unlock(&fastMutex); return true;}bool NRLAN103::CommMannager::CommRecv(ASDUbuff& asdu){ pthread_mutex_lock(&fastMutex); bool b=rcvQueue.empty(); if(!b) { asdu=rcvQueue[0]; rcvQueue.pop_front(); } pthread_mutex_unlock(&fastMutex); return(!b);}void NRLAN103::CommMannager::run(){ CommThread();}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?