📄 netcontrol.cpp
字号:
{ GetLog()->Error() << "(NetControl::SendMessage) ERROR: '" << GetName() << "' send returned error '" << strerror(errno) << "' " << endl; }}void NetControl::SendMessage(const Addr& addr, const string& msg){ TAddrMap::iterator iter = mClients.find(addr); if (iter == mClients.end()) { GetLog()->Error() << "(NetControl::SendMessage) ERROR: unknown client address '" << addr.getHostStr() << ":" << addr.getPort() << "'\n"; return; } SendMessage((*iter).second,msg);}void NetControl::AcceptTCPConnections(){ if ( (mSocketType != ST_TCP) || (mSocket.get() == 0) ) { return; } int fd = mSocket->getFD(); fd_set readfds; FD_ZERO(&readfds); FD_SET(fd,&readfds); timeval time; time.tv_sec = 0; time.tv_usec = 0; for(;;) { int ret = select(fd+1, &readfds, 0, 0, &time); if (ret == 0) { // no more connections pending break; } if (ret < 0) { GetLog()->Error() << "(NetControl) ERROR: '" << GetName() << "' select returned error on server socket " << DescribeSocketType() << ' ' << strerror(errno) << "\n" << "(NetControl) ERROR: closing server socket" << endl; mSocket->close(); mSocket.reset(); break; } try { Addr addr; shared_ptr<Socket> socket(mSocket->accept(addr)); int ret = socket->setNonBlocking(true); if (ret < 0) { GetLog()->Error() << "(NetControl) failed to set client socket to" << " non blocking mode with '" << strerror(errno) << "'. closing connection\n"; socket->close(); } else { AddClient(addr,socket); } } catch (AcceptErr error) { GetLog()->Error() << "(NetControl) '" << GetName() << "' failed to accept TCP connection with '" << error.what() << endl; break; } }}void NetControl::CloseDeadConnections(){ while (! mCloseClients.empty()) { RemoveClient(mCloseClients.front()); mCloseClients.pop_front(); }}void NetControl::StartCycle(){ // read any pending messages, for UDP new source addresses are // registered as new clients ReadMessages(); // if we manage a TCP server socket accept new client connections AcceptTCPConnections();}void NetControl::EndCycle(){ // close connections marked as dead during this cycle CloseDeadConnections();}void NetControl::ReadMessages(){ switch (mSocketType) { case ST_TCP: ReadTCPMessages(); break; case ST_UDP: ReadUDPMessages(); break; default: break; }}void NetControl::StoreFragment(const Addr& addr, int size){ TBufferMap::iterator msgIter = mBuffers.find(addr); if (msgIter == mBuffers.end()) { // allocate a new NetBuffer for the client mBuffers[addr] = (shared_ptr<NetBuffer> (new NetBuffer(addr,string(mBuffer.get(),size))) ); } else { // append to an existing NetBuffer (*msgIter).second->AddFragment(string(mBuffer.get(),size)); }}void NetControl::ReadUDPMessages(){ if (mSocket.get() == 0) { return; } int fd = mSocket->getFD(); fd_set readfds; FD_ZERO(&readfds); FD_SET(fd,&readfds); timeval time; time.tv_sec = 0; time.tv_usec = 0; for(;;) { int ret = select(fd+1, &readfds, 0, 0, &time); if (ret == 0) { // no data available break; } if (ret < 0) { GetLog()->Error() << "(NetControl) ERROR: ReadUDPSocket '" << GetName() << "' select returned error on server socket " << DescribeSocketType() << ' ' << strerror(errno) << endl; break; } // read fragment Addr from; int rval = mSocket->recv(mBuffer.get(), mBufferSize, from); if (rval < 0) { GetLog()->Error() << "(NetControl) ERROR: ReadUDPSocket '" << GetName() << "' recv returned error '" << strerror(errno) << "' " << endl; continue; } TAddrMap::iterator iter = mClients.find(from); if (iter == mClients.end()) { // a new client connected AddClient(from); } StoreFragment(from,rval); }}void NetControl::ReadTCPMessages(){ // generate a set of client socket fds fd_set client_fds; FD_ZERO(&client_fds); int maxFd = 0; for ( TAddrMap::iterator iter=mClients.begin(); iter != mClients.end(); ++iter ) { const int fd = (*iter).second->socket->getFD(); maxFd = std::max<int>(fd,maxFd); FD_SET(fd,&client_fds); } // test for pending fragments for(;;) { timeval time; time.tv_sec = 0; time.tv_usec = 0; fd_set test_fds = client_fds; int ret = select(maxFd+1, &test_fds, 0, 0, &time); if (ret == 0) { // no data available break; } if (ret < 0) { GetLog()->Error() << "(NetControl) ERROR: '" << GetName() << "' select returned error on client sockets '" << strerror(errno) << "' " << endl; break; } // read fragments for ( TAddrMap::iterator iter=mClients.begin(); iter != mClients.end(); ++iter ) { const int fd = (*iter).second->socket->getFD(); if (! FD_ISSET(fd, &test_fds)) { continue; } // read a fragment shared_ptr<Client>& client = (*iter).second; int rval = client->socket->recv(mBuffer.get(),mBufferSize); if (rval > 0) { StoreFragment(client->addr,rval); } else { if (rval < 0) { GetLog()->Error() << "(NetControl) ERROR: '" << GetName() << "' recv returned error on a client socket '" << strerror(errno) << "' " << endl; continue; } // (rval==0) indicates a close() on // the client side // mark the client connection to be // closed and exclude it from further // select() calls FD_CLR(fd,&client_fds); mCloseClients.push_back(client->addr); } } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -