int EpollTcpServer::init(int port, AbstractTcpHandler *handler, int threadCount) { DECLEAR_TCPSERVER_LOGGER; int ret = 0; if(threadCount <= 0) { LOGGER_WARN("EpollTcpServer::init: threadCount < 0.\n"); return -1; } this->mserverPort = port; this->mtcpHandler = handler; ret = this->createSocket(port); if(ret < 0) { LOGGER_WARN("EpollTcpServer::init: failed to create server socket on port: %1.\n", port); ret = -1; } else { ret = createHandlerThread(threadCount); if(ret < 0) { LOGGER_WARN("EpollTcpServer::init: failed to create handler thread.\n"); ret = -2; } } return ret; }
int EpollTcpServer::createSocket(int port) { DECLEAR_TCPSERVER_LOGGER; int ret = 0; struct sockaddr_in servaddr; this->mserverFd = socket(AF_INET, SOCK_STREAM, 0); if(this->mserverFd < 0) { LOGGER_WARN("EpollTcpServer::createSocket: failed to create server socket fd.\n"); ret = -1; } else { bzero(&servaddr,sizeof(servaddr)); servaddr.sin_family = AF_INET; servaddr.sin_port = htons(port); servaddr.sin_addr.s_addr = htonl(INADDR_ANY); int reuseFlag = 1; if(setsockopt(this->mserverFd, SOL_SOCKET, SO_REUSEADDR, &reuseFlag, sizeof(reuseFlag)) < 0) { LOGGER_WARN("EpollTcpServer::createSocket: failed to set socket reuse option.\n"); ret = -2; } else { if(this->setSocketNoBlock(this->mserverFd, true) < 0) { LOGGER_WARN("EpollTcpServer::createSocket: failed to set socket to NONBLOCK.\n"); ret = -3; } if(bind(this->mserverFd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr)) < 0) { LOGGER_WARN("EpollTcpServer::createSocket: bind failed: %1.\n", strerror(errno)); ret = -4; } else { if(listen(this->mserverFd, MAX_TCP_LISTEN_QUEUE_SIZE)) { LOGGER_WARN("EpollTcpServer::createSocket: failed to listen: %1.\n", strerror(errno)); ret = -5; } } } } return ret; }
bool CUserMgr::_HandlePacket_UserLogin(Packet* pack) { Message::ClientLogin msg; PROTOBUF_CMD_PARSER(pack, msg); CLinker* server = GateServer.getServerByType(CBaseServer::Linker_Server_Game); if (!server) { LOGGER_ERROR("User login failed. Cannot find gameserver: user %lld", msg.uid()); GETCLIENTNET(&GateServer)->shutdown(pack->GetNetID()); return false; } CUser* user = UserMgr.Create(pack->GetNetID()); if (!user) { LOGGER_ERROR("User login failed. Cannot create user: %lld", msg.uid()); GETCLIENTNET(&GateServer)->shutdown(pack->GetNetID()); return false; } CUser* oldUser = GetUserByUID(msg.uid()); if (oldUser) { Displace(oldUser); LOGGER_WARN("user %lld relogin, displace the older.", msg.uid()); } TMV t = time(NULL); user->m_id = msg.uid(); user->m_worldID = server->m_worldID; user->m_svrID = server->m_nID; user->m_ClientSock = pack->GetNetID(); user->m_GameSock = server->m_Socket; user->m_HeartTime = t; user->m_CanCreate = false; user->m_PackCount = 0; user->m_PackTime = t; user->m_AccessToken = msg.accesstoken(); ThreadLib::CreateByPool(httpCheckUserThread, user); return true; }
int EpollTcpServer::setSocketNoBlock(int fd, bool noblock) { DECLEAR_TCPSERVER_LOGGER; int flags = fcntl(fd, F_GETFL, 0); if(noblock) { flags |= O_NONBLOCK; } else { flags &= (~ O_NONBLOCK); } if(fcntl(fd, F_SETFL, flags) == -1) { LOGGER_WARN("EpollTcpServer::createSocket: failed to set socket to %1.\n", noblock ? "NO block":"block"); return -1; } return 0; }
int EpollTcpServer::createHandlerThread(int threadCount) { DECLEAR_TCPSERVER_LOGGER; int ret = 0; int newIndex = 0; for(newIndex = 0;newIndex < threadCount; ++newIndex) { TcpHandlerThread *tht = new TcpHandlerThread; ret = tht->init(this->mserverFd, &mserverSocketMutex, this->mtcpHandler); if(ret < 0) { LOGGER_WARN("EpollTcpServer::createHandlerThread: failed to init tcp handler thread.\n"); delete tht; break; } else { this->mthreads.push_back(tht); } } // if could not alloc as many threads as the threadCount says, delete all the threads already alloced. if(newIndex < threadCount) { for(int j = 0; j < newIndex; ++j) { delete this->mthreads[j]; } this->mthreads.clear(); ret = -1; } return ret; }
/** ** \~french * \brief Fonction principale de l'outil createNodata * \details Tout est contenu dans cette fonction. Le "cropage" se fait grâce à la classe TiffNodataManager, et le tuilage / compression est géré par TiledTiffWriter * \param[in] argc nombre de paramètres * \param[in] argv tableau des paramètres * \return code de retour, 0 en cas de succès, -1 sinon ** \~english * \brief Main function for tool createNodata * \details All instrcutions are in this function. the crop is handled by the class TiffNodataManager and TiledTiffWriter make image tiled and compressed. * \param[in] argc parameters number * \param[in] argv parameters array * \return return code, 0 if success, -1 otherwise */ int main ( int argc, char **argv ) { char* input = 0, *output = 0; int tileWidth = 256, tileHeight = 256; Compression::eCompression compression = Compression::NONE; bool crop = false; bool debugLogger=false; /* Initialisation des Loggers */ Logger::setOutput ( STANDARD_OUTPUT_STREAM_FOR_ERRORS ); Accumulator* acc = new StreamAccumulator(); Logger::setAccumulator ( INFO , acc ); Logger::setAccumulator ( WARN , acc ); Logger::setAccumulator ( ERROR, acc ); Logger::setAccumulator ( FATAL, acc ); std::ostream &logw = LOGGER ( WARN ); logw.precision ( 16 ); logw.setf ( std::ios::fixed,std::ios::floatfield ); // Récupération des paramètres for ( int i = 1; i < argc; i++ ) { if ( !strcmp ( argv[i],"-crop" ) ) { crop = true; continue; } if ( argv[i][0] == '-' ) { switch ( argv[i][1] ) { case 'h': // help usage(); exit ( 0 ); case 'd': // debug logs debugLogger = true; break; case 'c': // compression if ( ++i == argc ) { error ( "Error in -c option", -1 ); } if ( strncmp ( argv[i], "none",4 ) == 0 || strncmp ( argv[i], "raw",3 ) == 0 ) { compression = Compression::NONE; } else if ( strncmp ( argv[i], "png",3 ) == 0 ) { compression = Compression::PNG; } else if ( strncmp ( argv[i], "jpg",3 ) == 0 ) { compression = Compression::JPEG; } else if ( strncmp ( argv[i], "lzw",3 ) == 0 ) { compression = Compression::LZW; } else if ( strncmp ( argv[i], "zip",3 ) == 0 ) { compression = Compression::DEFLATE; } else if ( strncmp ( argv[i], "pkb",3 ) == 0 ) { compression = Compression::PACKBITS; } else { error ( "Unknown compression : " + string(argv[i]), -1 ); } break; case 't': if ( i+2 >= argc ) { error("Error in -t option", -1 ); } tileWidth = atoi ( argv[++i] ); tileHeight = atoi ( argv[++i] ); break; default: error ( "Unknown option : " + string(argv[i]) ,-1 ); } } else { if ( input == 0 ) input = argv[i]; else if ( output == 0 ) output = argv[i]; else { error ( "Argument must specify ONE input file and ONE output file", 2 ); } } } if (debugLogger) { // le niveau debug du logger est activé Logger::setAccumulator ( DEBUG, acc); std::ostream &logd = LOGGER ( DEBUG ); logd.precision ( 16 ); logd.setf ( std::ios::fixed,std::ios::floatfield ); } if ( input == 0 || output == 0 ) { error ("Argument must specify one input file and one output file", -1); } FileImageFactory FIF; if (crop && compression != Compression::JPEG) { LOGGER_WARN("Crop option is reserved for JPEG compression"); crop = false; } // For jpeg compression with crop option, we have to remove white pixel, to avoid empty bloc in data if ( crop ) { LOGGER_DEBUG ( "Open image to read" ); // On récupère les informations nécessaires pour appeler le nodata manager FileImage* tmpSourceImage = FIF.createImageToRead(input); int spp = tmpSourceImage->channels; int bps = tmpSourceImage->getBitsPerSample(); SampleFormat::eSampleFormat sf = tmpSourceImage->getSampleFormat(); delete tmpSourceImage; if ( bps == 8 && sf == SampleFormat::UINT ) { TiffNodataManager<uint8_t> TNM ( spp, white, true, fastWhite,white ); if ( ! TNM.treatNodata ( input,input ) ) { error ( "Unable to treat white pixels in this image : " + string(input), -1 ); } } else { LOGGER_WARN( "Crop option ignored (only for 8-bit integer images) for the image : " << input); } } LOGGER_DEBUG ( "Open image to read" ); FileImage* sourceImage = FIF.createImageToRead(input); if (sourceImage == NULL) { error("Cannot read the source image", -1); } if (debugLogger) { sourceImage->print(); } Rok4ImageFactory R4IF; Rok4Image* rok4Image = R4IF.createRok4ImageToWrite( output, BoundingBox<double>(0.,0.,0.,0.), -1, -1, sourceImage->getWidth(), sourceImage->getHeight(), sourceImage->channels, sourceImage->getSampleFormat(), sourceImage->getBitsPerSample(), sourceImage->getPhotometric(), compression, tileWidth, tileHeight ); rok4Image->setExtraSample(sourceImage->getExtraSample()); if (rok4Image == NULL) { error("Cannot create the ROK4 image to write", -1); } if (debugLogger) { rok4Image->print(); } LOGGER_DEBUG ( "Write" ); if (rok4Image->writeImage(sourceImage, crop) < 0) { error("Cannot write ROK4 image", -1); } LOGGER_DEBUG ( "Clean" ); // Nettoyage delete acc; delete sourceImage; delete rok4Image; return 0; }