AREXPORT void ArNetServer::runOnce(void) { ArSocket acceptingSocket; ArSocket *socket; char *str; std::list<ArSocket *> removeList; std::list<ArSocket *>::iterator it; ArArgumentBuilder *args = NULL; std::string command; if (!myOpened) { return; } lock(); // get any new sockets that want to connect while (myServerSocket.accept(&acceptingSocket) && acceptingSocket.getFD() >= 0) { acceptingSocket.setNonBlock(); // see if we want more sockets if (!myMultipleClients && (myConns.size() > 0 || myConnectingConns.size() > 0)) { // we didn't want it, so politely tell it to go away acceptingSocket.writeString("Conn refused."); acceptingSocket.writeString( "Only client allowed and it is already connected."); acceptingSocket.close(); ArLog::log(ArLog::Terse, "ArNetServer not taking multiple clients and another client tried to connect from %s.", acceptingSocket.getIPString()); } else { // we want the client so we put it in our list of connecting // sockets, which means that it is waiting to give its password socket = new ArSocket; socket->setLogWriteStrings(myLoggingDataSent); socket->transfer(&acceptingSocket); socket->writeString("Enter password:"******"Client connecting from %s.", socket->getIPString()); } } // now we read in data from our connecting sockets and see if // they've given us the password for (it = myConnectingConns.begin(); it != myConnectingConns.end(); ++it) { socket = (*it); // read in what the client has to say if ((str = socket->readString()) != NULL) { if (str[0] == '\0') continue; // now see if the word matchs the password if (myPassword == str) { ArLog::log(ArLog::Normal, "Client from %s gave password and connected.", socket->getIPString()); myConns.push_front(socket); removeList.push_front(socket); internalGreeting(socket); } else { socket->close(); myDeleteList.push_front(socket); ArLog::log(ArLog::Terse, "Client from %s gave wrong password and is being disconnected.", socket->getIPString()); } } // if we couldn't read a string it means we lost a connection else { ArLog::log(ArLog::Normal, "Connection to %s lost.", socket->getIPString()); socket->close(); myDeleteList.push_front(socket); } } // now we clear out the ones we want to remove from our connecting // clients list while ((it = removeList.begin()) != removeList.end()) { socket = (*it); myConnectingConns.remove(socket); removeList.pop_front(); } // now we read in data from our connecting sockets and see if // they've given us the password for (it = myConns.begin(); it != myConns.end() && myOpened; ++it) { socket = (*it); // read in what the client has to say while ((str = socket->readString()) != NULL) { // if this is null then there wasn't anything said if (str[0] == '\0') break; // make sure we read something // set up the arguments and then call the function for the // argument args = new ArArgumentBuilder; args->addPlain(str); //args->log(); parseCommandOnSocket(args, socket); delete args; args = NULL; } // if str was NULL we lost connection if (str == NULL) { ArLog::log(ArLog::Normal, "Connection to %s lost.", socket->getIPString()); socket->close(); myDeleteList.push_front(socket); } } // now we delete the ones we want to delete (we could do this above // but then it wouldn't be symetrical with above) while ((it = myDeleteList.begin()) != myDeleteList.end()) { socket = (*it); myConnectingConns.remove(socket); myConns.remove(socket); socket->close(); delete socket; myDeleteList.pop_front(); } if (myWantToClose) { close(); } unlock(); }
void ArCentralManager::netServerSwitch(ArServerClient *client, ArNetPacket *packet) { char robotName[512]; std::string uniqueName; robotName[0] = '\0'; //printf("robotName before '%s'\n", robotName); packet->bufToStr(robotName, sizeof(robotName)); ArNetPacket sendPacket; /// acknowledge the switch client->sendPacketTcp(&sendPacket); ArSocket *clientSocket = new ArSocket; clientSocket->transfer(client->getTcpSocket()); client->tcpCallback(); client->forceDisconnect(true); // make the basis of the unique name if (robotName[0] != '\0') uniqueName = robotName; else uniqueName = client->getIPString(); //printf("Starting with '%s'\n", uniqueName.c_str()); myDataMutex.lock(); // walk through and make the name unique std::list<ArCentralForwarder *>::iterator fIt; ArCentralForwarder *forwarder; /* the old code that made the names unique bool nameIsUnique = false; while (!nameIsUnique) { nameIsUnique = true; for (fIt = myForwarders.begin(); fIt != myForwarders.end() && nameIsUnique; fIt++) { forwarder = (*fIt); if (strcasecmp(forwarder->getRobotName(), uniqueName.c_str()) == 0) nameIsUnique = false; } if (!nameIsUnique) uniqueName += "_"; } */ // the new code that drops the duplicates and replaces it with the same name for (fIt = myForwarders.begin(); fIt != myForwarders.end(); fIt++) { forwarder = (*fIt); if (strcasecmp(forwarder->getRobotName(), uniqueName.c_str()) == 0) { ArLog::log(ArLog::Normal, "ArCentralManager: Will drop old duplicate connection for %s", uniqueName.c_str()); forwarder->willReplace(); } } // remove any pending client duplicates while (removePendingDuplicateConnections(uniqueName.c_str())); // end of new code, though it also had reordering down below in the runthread myClientSockets.push_back(clientSocket); myClientNames.push_back(uniqueName); //printf("robotName after '%s'\n", robotName); // just print out the switch request name if its the same as it came in as if (strcmp(uniqueName.c_str(), robotName) == 0) ArLog::log(ArLog::Normal, "Got switch request from %s from %s", client->getIPString(), uniqueName.c_str()); // otherwise let them know what the unique name is if (strcmp(uniqueName.c_str(), robotName) != 0) ArLog::log(ArLog::Normal, "Got switch request from %s from %s that started as %s", client->getIPString(), uniqueName.c_str(), robotName); //printf("Ended with '%s'\n", uniqueName.c_str()); myDataMutex.unlock(); }