⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 netmanager.cpp~

📁 查看局域网的信息,类似网上邻居的功能,例如查看哪台计算机在线等
💻 CPP~
📖 第 1 页 / 共 2 页
字号:
   //try to serve the request   for (Client *tmpClient=clients.first(); tmpClient!=0; tmpClient=clients.next())   {      getDebug()<<"NetManager::serveAndClean: trying to get info"<<endl;      tmpClient->tryToGetInfo();   };      //try to delete served the clients   for (Client* tmpClient=clients.first();tmpClient!=0; tmpClient=clients.next())   {      //if we served the client or if he's already half a minute      //connected remove it      //this way we get rid of clients if something went wrong and      //maybe it's even a security point, I don't know      if ((tmpClient->done()) || (tmpClient->age()>30))      {         getDebug()<<"NetManager::serveAndClean: removing Client"<<endl;         clients.remove(tmpClient);         tmpClient=clients.first();      };   };};void NetManager::scan(){   getDebug()<<"NetManager::scan()"<<endl;   if (isBeingScanned()) return;   time_t currentTime=time(0);   getDebug()<<"currentTime: "<<currentTime<<" lastUpdate: "<<m_lastUpdate<<endl;   if ((currentTime-m_lastUpdate)<m_refreshTime) return;   getDebug()<<"NetManager::scan: scanning..."<<endl;   m_isBeingScanned=1;   int fileDescr[2];   ::pipe(fileDescr);   getDebug()<<"NetScanner::scan: file-descr[0]: "<<fileDescr[0]<<endl;   getDebug()<<"NetScanner::scan: file-descr[1]: "<<fileDescr[1]<<endl;   int pid=fork();	if (pid==-1)	{      getDebug()<<"NetScanner::scan: error occured"<<endl;      return;   }   else if (pid!=0)   {      //parent      ::close(fileDescr[1]);      m_pipeFD=fileDescr[0];      m_childPid=pid;      return;   };   //child   procId="** child ** ";   getDebug()<<" NetManager::scan: a child was born"<<endl;   if (m_strictMode)   {      getDebug()<<" NetManager::scan: scanning myself in strict mode, becoming serverServer"<<endl;      doScan();      //in the child we don't have to call setServerServer()      //since this opens the listening socket, what has to be done      //in the parent process      m_serverServer=1;   }   else   {      int serverAddress=findServerServer();      if (serverAddress==0)      {         getDebug()<<" NetManager::scan: scanning myself, becoming serverServer"<<endl;         doScan();         //in the child we don't have to call setServerServer()         //since this opens the listening socket, what has to be done         //in the parent process         m_serverServer=1;      }      else      {         getDebug()<<" NetManager::scan: getting list from serverServer"<<endl;         getListFromServerServer(serverAddress);         m_serverServer=0;      };   };   getDebug()<<" NetScanner::scan: sending information to parent process"<<endl;   writeDataToFD(fileDescr[1],m_serverServer);   getDebug()<<" NetScanner::scan: closed FD: "<<::close(fileDescr[1])<<endl;   getDebug()<<" NetScanner::scan: exiting now"<<endl;   ::exit(0);};int NetManager::writeDataToFD(int fd, int serverServer){   getDebug()<<" NetManager::writeDataToFD fd="<<fd<<endl;   m_serveCount++;   char buffer[1024];      int length;   for (Node* tmpNode=hostList->first(); tmpNode!=0; tmpNode=hostList->next())   {      sprintf(buffer,"%u %s\n",tmpNode->ip,tmpNode->name.left(1000).c_str());      length=strlen(buffer)+1;      const char *currentBuf=buffer;      //make sure that everything is written      while (length>0)      {         int result=::write(fd,currentBuf,length);         getDebug()<<"NetManager::writeDataToFD: wrote "<<result<<" bytes"<<endl;         if (result==-1)         {            perror("hmmpf: ");            return 0;         };         length-=result;         currentBuf+=result;      };   };   //and a last line   sprintf(buffer,"%d succeeded\n",serverServer);   length=strlen(buffer)+1;   const char *currentBuf=buffer;   //make sure that everything is written   while (length>0)   {      int result=::write(fd,currentBuf,length);      if (result==-1) return 0;      length-=result;      currentBuf+=result;   };   return 1;};int NetManager::readDataFromFD(int fd){   getDebug()<<"NetManager::readDataFromFD"<<endl;   char tmpBuf[64*1024];   int result=::read(fd,tmpBuf,64*1024);   getDebug()<<"NetManager::readDataFromFD: read "<<result<<" bytes"<<endl;   if (result==-1) return -1;   if (result==0)   {      getDebug()<<"NetManager::readDataFromFD: FD was closed"<<endl;      return 0;   };   char *newBuf=new char[m_receivedBytes+result];   if (m_receiveBuffer!=0) memcpy(newBuf,m_receiveBuffer,m_receivedBytes);   memcpy(newBuf+m_receivedBytes,tmpBuf,result);   m_receivedBytes+=result;   if (m_receiveBuffer!=0) delete [] m_receiveBuffer;   m_receiveBuffer=newBuf;   return 1;};int NetManager::processScanResults(){   getDebug()<<"NetManager::processScanResults"<<endl;   if (m_receiveBuffer==0) return 0;   SimpleList<Node> *newNodes=new SimpleList<Node>;   char *tmpBuf=m_receiveBuffer;   int bytesLeft=m_receivedBytes;   int tmpIP;   getDebug()<<"m_receivedBytes: "<<m_receivedBytes<<" bytesLeft: "<<bytesLeft<<endl;   //this should be large enough for a name   //and the stuff which is inserted into the buffer   //comes only from ourselves   char tmpName[1024*4];   while (bytesLeft>0)   {      if ((memchr(tmpBuf,0,bytesLeft)==0) || (memchr(tmpBuf,int('\n'),bytesLeft)==0))      {         delete newNodes;         hostList->clear();         m_lastUpdate=time(0);         delete [] m_receiveBuffer;         m_receiveBuffer=0;         m_receivedBytes=0;         m_isInformed=1;         m_isBeingScanned=0;         return 0;      };      //getDebug()<<"NetManager::processScanResults: processing -"<<tmpBuf;      sscanf(tmpBuf,"%u %s\n",&tmpIP,tmpName);      //since we check for 0 and \n with memchr() we can be sure      //at this point that tmpBuf is correctly terminated      int length=strlen(tmpBuf)+1;      bytesLeft-=length;      tmpBuf+=length;      getDebug()<<"length: "<<length<<" bytesLeft: "<<bytesLeft<<endl;      if ((bytesLeft==0) && (strstr(tmpName,"succeeded")!=0) && ((tmpIP==0) ||(tmpIP==1)))      {         getDebug()<<"NetManager::processScanResults: succeeded :-)"<<endl;         delete hostList;         hostList=newNodes;         m_lastUpdate=time(0);         delete [] m_receiveBuffer;         m_receiveBuffer=0;         m_receivedBytes=0;         m_isInformed=1;         m_isBeingScanned=0;         adjustRefreshTime(tmpIP);         enableServerServer(tmpIP);         //m_serverServer=tmpIP;         return 1;      }      else      {         //getDebug()<<"NetManager::processScanResults: adding host: "<<tmpName<<" with ip: "<<tmpIP<<endl;         newNodes->append(Node(tmpName,tmpIP));      };   };   //something failed :-(   delete newNodes;   hostList->clear();   m_lastUpdate=time(0);   delete [] m_receiveBuffer;   m_receiveBuffer=0;   m_receivedBytes=0;   m_isInformed=1;   m_isBeingScanned=0;   getDebug()<<"NetScanner::processScanResult: finished"<<endl;   return 0;};void NetManager::adjustRefreshTime(int serverServer){   //we are becoming server server   if (((m_serverServer==0) && (serverServer)) || (m_servedThisPeriod))   {      m_increasedRefreshTime=0;      m_refreshTime=m_initialRefreshTime;   }   //nobody accessed the server since the last update   //so increase the refresh time   //this should happen more seldom to the serverServer   //than to others   else   {      //up to the 16 times refresh time      if (m_increasedRefreshTime<4)      {         m_increasedRefreshTime++;         m_refreshTime*=2;      };   };   m_servedThisPeriod=0;   };void NetManager::enableServerServer(int on){   getDebug()<<"NetManager::enableServerServer: "<<on<<endl;   //in strictMode we don't listen to broadcasts from the network   if (m_strictMode) return;   m_serverServer=on;   if (on)   {      //nothing has to be done      if (m_bcFD!=-1) return;      // otherwise create the socket which will listen for broadcasts      sockaddr_in my_addr;      my_addr.sin_family=AF_INET;      my_addr.sin_port=htons(m_basePort);      my_addr.sin_addr.s_addr=0;      m_bcFD=::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);      if (m_bcFD==-1)      {         getDebug()<<"NetManager::enableServerServer: socket() failed"<<endl;         m_serverServer=0;         return;      };      int on(1);      int result=setsockopt(m_bcFD, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));      if (result!=0)      {         getDebug()<<"NetManager::enableServerServer: setsockopt(SO_REUSEADDR) failed"<<endl;         m_serverServer=0;         ::close(m_bcFD);         m_bcFD=-1;         return;      };      result=::bind(m_bcFD, (struct sockaddr *) &my_addr, sizeof(my_addr));      if (result!=0)      {         getDebug()<<"NetManager::enableServerServer: bind (UDP) failed"<<endl;         m_serverServer=0;         ::close(m_bcFD);         m_bcFD=-1;         return;      };   }   else   {      ::close(m_bcFD);      m_bcFD=-1;   };};int NetManager::findServerServer(){   getDebug()<<" NetManager::findServerServer"<<endl;   //actually this should never be called in strictMode   if (m_strictMode) return 0;   if (!validator.isValid(m_broadcastAddress))   {      getDebug()<<" NetManager::findServerServer: invalid broadcastAddress"<<endl;      return 0;   };   //create a socket for sending the broadcast   //we don't have to set SO_REUSEADDR, since we don't call bind()   //to this socket   int requestFD=::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);   if (requestFD==-1)   {      getDebug()<<" NetManager::findServerServer: could not create request socket"<<endl;      return 0;   };   int on(1);   //this is actually the only socket which will send broacasts   int result=setsockopt(requestFD, SOL_SOCKET, SO_BROADCAST,&on, sizeof(on));   if (result!=0)   {      getDebug()<<"setsockopt(SO_BROADCAST) failed"<<endl;      ::close(requestFD);      return 0;   };      //create a socket for receiving the answers   int answerFD=::socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP);   if (answerFD==-1)   {      getDebug()<<" NetManager::findServerServer"<<endl;      ::close(requestFD);      return 0;   };      //since this socket will be bound, we have to set SO_REUSEADDR   result=setsockopt(answerFD, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on));   if (result!=0)   {      getDebug()<<"setsockopt(SO_REUSEADDR) failed"<<endl;      ::close(answerFD);      ::close(requestFD);      return 0;   };      sockaddr_in my_addr;   my_addr.sin_family=AF_INET;   my_addr.sin_port=htons(m_basePort+1);   my_addr.sin_addr.s_addr=0;   //this one has to be bound   result=::bind(answerFD, (struct sockaddr *) &my_addr, sizeof(my_addr));   if (result!=0)   {      getDebug()<<"bind (UDP) failed"<<endl;      ::close(answerFD);      ::close(requestFD);      return 0;   };      //now send the broadcast   struct sockaddr_in sAddr;   sAddr.sin_addr.s_addr=m_broadcastAddress;   sAddr.sin_family=AF_INET;   sAddr.sin_port=htons(m_basePort);   socklen_t length(sizeof(sockaddr_in));   getDebug()<<" NetManager::findServerServer: broadcasting to: "   <<ios::hex<<m_broadcastAddress<<ios::dec<<endl;      MyFrameType requestFrame;   requestFrame.id=htonl(MY_ID);   requestFrame.unused1=htonl(getppid());   requestFrame.unused2=htonl(m_startedAt);   result=::sendto(requestFD,(void*)&requestFrame,sizeof(requestFrame),0,(sockaddr*)&sAddr,length);   ::close(requestFD);   if (result!=MYFRAMELENGTH)   {      getDebug()<<" NetManager::findServerServer: sent wrong number of bytes: "<<result<<endl;      ::close(answerFD);      return 0;   };   //wait for an answer   struct timeval tv;   tv.tv_sec=0;   tv.tv_usec=1000*250; //0.1 sec   fd_set fdSet;   FD_ZERO(&fdSet);   FD_SET(answerFD,&fdSet);   result=select(answerFD+1,&fdSet,0,0,&tv);   if (result<0)   {      getDebug()<<" NetManager::findServerServer: select() failed: "<<result<<endl;      getDebug()<<" NetManager::findServerServer: answerFD="<<answerFD<<endl;      perror("select:");      ::close(answerFD);      return 0;   }   if (result==0)   {      getDebug()<<" NetManager::findServerServer: nobody answered "<<endl;      ::close(answerFD);      return 0;   }   getDebug()<<"received offer "<<endl;   struct sockaddr_in addr;   length=sizeof(sockaddr_in);   char buf[1024];   result=recvfrom(answerFD, (void*)buf, 1024, 0, (sockaddr*) &addr,&length);   if (result!=MYFRAMELENGTH)   {      getDebug()<<" NetManager::findServerServer: wrong number of bytes: "<<result<<endl;      ::close(answerFD);      return 0;   };   MyFrameType *frame=(MyFrameType*)(void*)buf;   //wrong identifier ?   if (ntohl(frame->id)!=MY_ID)   {      getDebug()<<" NetManager::findServerServer: wrong id"<<endl;      ::close(answerFD);      return 0;   };   getDebug()<<"received from "<<inet_ntoa(addr.sin_addr)<<endl;   ::close(answerFD);   //return the ip of the server server in network byte order   return addr.sin_addr.s_addr;};void NetManager::getListFromServerServer( int address){   getDebug()<<"NetManager::getListFromServerServer"<<endl;   //actually we should never get here in strictMode   if (m_strictMode) return;   //open a tcp socket to the serverserver   int serverServerFD=::socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);   if (serverServerFD==-1)      return;   sockaddr_in addr;   //we get the address already in network byte order   addr.sin_addr.s_addr=address;   addr.sin_family=AF_INET;   addr.sin_port=htons(m_basePort);   int result=::connect(serverServerFD,(sockaddr*)&addr,sizeof(addr));   if (result!=0)   {      ::close(serverServerFD);      return;   };   do   {      result=readDataFromFD(serverServerFD);   } while (result==1);   ::close(serverServerFD);   processScanResults();   getDebug()<<"NetManager::getListFromServerServer succeeded"<<endl;};void NetManager::printState(){   cerr<<"LAN Information Server Lisa 0.1\nAlexander Neundorf <neundorf@kde.org>\n";   cerr<<"Reading options from config file: "<<m_usedConfigFileName<<endl;   cerr<<"StrictMode: "<<m_strictMode<<endl;   cerr<<"ServerServer: "<<m_serverServer<<endl;   cerr<<"UseNmblookup: "<<m_useNmblookup<<endl;   cerr<<"Pinging: "<<ipRangeStr<<endl;   cerr<<"Allowed hosts: "<<validator.validAddresses()<<endl;   cerr<<"Broadcasting to: "<<ios::hex<<ntohl(m_broadcastAddress)<<ios::dec<<endl;   cerr<<"Initial update period: "<<m_initialRefreshTime<<" seconds"<<endl;   cerr<<"Current update period: "<<m_refreshTime<<" seconds"<<endl;   cerr<<"Last update: "<<time(0)-m_lastUpdate<<" seconds over"<<endl;   cerr<<"Waiting "<<m_firstWait<<" 1/100th seconds for echo answers on the first try"<<endl;   cerr<<"Waiting "<<m_secondWait<<" 1/100th seconds for echo answers on the second try"<<endl;   cerr<<"Sending "<<m_maxPings<<" echo requests at once"<<endl;   cerr<<"Publishing unnamed hosts: "<<m_deliverUnnamedHosts<<endl;   cerr<<"Already served "<<m_serveCount<<" times"<<endl;};//this one is not used at the moment/*int NetManager::uptime(){   return (time(0)-m_startedAt);};*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -