diff --git a/source/glest_game/main/main.cpp b/source/glest_game/main/main.cpp index b10655ea..5389355a 100644 --- a/source/glest_game/main/main.cpp +++ b/source/glest_game/main/main.cpp @@ -2950,13 +2950,13 @@ int glestMain(int argc, char** argv) { else { #ifdef _WIN32 - int localeBufferSize = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, NULL, 0); - wchar_t *sysLocale = new wchar_t[localeBufferSize]; + int localeBufferSize = GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, NULL, 0); + wchar_t *sysLocale = new wchar_t[localeBufferSize]; GetLocaleInfo(LOCALE_SYSTEM_DEFAULT, LOCALE_SISO639LANGNAME, sysLocale,localeBufferSize); //String langValue(sysLocale); //const char *lang_locale = langValue.c_str(); - char langValue[1024]=""; + char langValue[1024]=""; wcstombs(langValue,sysLocale, 1023); const char *lang_locale = &langValue[0]; #else @@ -3548,6 +3548,10 @@ int glestMain(int argc, char** argv) { cinfd[0].events = POLLIN; #else h = GetStdHandle(STD_INPUT_HANDLE); + //DWORD dwMode; + //GetConsoleMode(h, &dwMode); + //SetConsoleMode(h, dwMode & ~ENABLE_MOUSE_INPUT); + FlushConsoleInputBuffer(h); #endif } @@ -3573,36 +3577,72 @@ int glestMain(int argc, char** argv) { // line buffer input. This does work okay as long as the user doesn't enter characters // without pressing enter, and then try to end the server another way (say a remote // console command), in which case we'll still be waiting for the stdin EOL and hang. - if (WaitForSingleObject(h, 0) == WAIT_OBJECT_0) + + DWORD saveMode; + GetConsoleMode(h, &saveMode); + DWORD dwMode = saveMode; + dwMode &= ~ENABLE_MOUSE_INPUT; + dwMode &= ~ENABLE_WINDOW_INPUT; + SetConsoleMode(h, dwMode); + + bool gotData = (WaitForSingleObject(h, 0) == WAIT_OBJECT_0); + SetConsoleMode(h, saveMode); + if(gotData == true) #endif { - getline(cin, command); - cin.clear(); + bool skip = true; +#ifdef WIN32 + DWORD nNumberOfCharsToRead = 1024; + DWORD nRead = 0; + INPUT_RECORD irInRec[1025]; + + PeekConsoleInput(h,&irInRec[0],nNumberOfCharsToRead,&nRead); + for(int i = 0; i < nRead; ++i) { + INPUT_RECORD &inr = irInRec[i]; - printf("server command [%s]\n",command.c_str()); - if(command == "quit") { - break; + //printf("inr.EventType = %d\n",inr.EventType); + if(inr.EventType == KEY_EVENT) { + if(inr.Event.KeyEvent.bKeyDown) { + char cHoldKey = inr.Event.KeyEvent.uChar.AsciiChar; + if(cHoldKey == '\r') { + skip = false; + break; + } + } + } } +#else + skip = false; +#endif + if(skip == false) { + getline(cin, command); + cin.clear(); + + printf("server command [%s]\n",command.c_str()); + if(command == "quit") { + break; + } #ifndef WIN32 - if (cinfd[0].revents & POLLNVAL) { - printf("invalid file descriptor\n"); - } - if (cinfd[0].revents & POLLERR) { - printf("error in file descriptor\n"); - } - if (cinfd[0].revents & POLLHUP) { - printf("hang up in file descriptor\n"); - } + if (cinfd[0].revents & POLLNVAL) { + printf("invalid file descriptor\n"); + } + if (cinfd[0].revents & POLLERR) { + printf("error in file descriptor\n"); + } + if (cinfd[0].revents & POLLHUP) { + printf("hang up in file descriptor\n"); + } - if(pollresult < 0) { - printf("pollresult = %d errno = %d [%s]\n",pollresult,pollerror,strerror(pollerror)); + if(pollresult < 0) { + printf("pollresult = %d errno = %d [%s]\n",pollresult,pollerror,strerror(pollerror)); - cinfd[0].fd = fileno(stdin); - cinfd[0].events = POLLIN; - } + cinfd[0].fd = fileno(stdin); + cinfd[0].events = POLLIN; + } #endif + } } } //printf("looping\n"); diff --git a/source/glest_game/network/connection_slot.cpp b/source/glest_game/network/connection_slot.cpp index 0589c2cb..b464de8f 100644 --- a/source/glest_game/network/connection_slot.cpp +++ b/source/glest_game/network/connection_slot.cpp @@ -385,9 +385,9 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); - Socket *newSocket = serverInterface->getServerSocket()->accept(); + Socket *newSocket = serverInterface->getServerSocket()->accept(false); - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] called accept new client connection playerIndex = %d\n",__FILE__,__FUNCTION__,__LINE__,playerIndex); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] called accept new client connection playerIndex = %d newSocket = %p\n",__FILE__,__FUNCTION__,__LINE__,playerIndex,newSocket); if(newSocket != NULL) { // Set Socket as non-blocking newSocket->setBlock(false); @@ -436,14 +436,19 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); } + else { + close(); + return; + } //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - } + //} //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); //send intro message when connected - if(hasData == true && this->isConnected() == true) { + //if(hasData == true && this->isConnected() == true) { + if(this->isConnected() == true) { //RandomGen random; //sessionKey = random.randRange(-100000, 100000); srand(time(NULL) / (this->playerIndex + 1)); @@ -473,6 +478,7 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); //} } + } } } //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); @@ -707,14 +713,14 @@ void ConnectionSlot::update(bool checkForNewClients,int lockedSlotIndex) { throw runtime_error(szBuf); } - GameSettings gameSettings; - networkMessageLaunch.buildGameSettings(&gameSettings); + GameSettings gameSettingsBuffer; + networkMessageLaunch.buildGameSettings(&gameSettingsBuffer); //printf("Connection slot got networkMessageLaunch.getMessageType() = %d, got map [%s]\n",networkMessageLaunch.getMessageType(),gameSettings.getMap().c_str()); //printf("\n\n\n\n=====Connection slot got settings:\n%s\n",gameSettings.toString().c_str()); - this->serverInterface->setGameSettings(&gameSettings,false); - this->serverInterface->broadcastGameSetup(&gameSettings); + //this->serverInterface->setGameSettings(&gameSettingsBuffer,false); + this->serverInterface->broadcastGameSetup(&gameSettingsBuffer, true); if(networkMessageLaunch.getMessageType() == nmtLaunch) { this->serverInterface->setMasterserverAdminRequestLaunch(true); diff --git a/source/glest_game/network/server_interface.cpp b/source/glest_game/network/server_interface.cpp index a4952e94..3010b600 100644 --- a/source/glest_game/network/server_interface.cpp +++ b/source/glest_game/network/server_interface.cpp @@ -1708,10 +1708,17 @@ bool ServerInterface::launchGame(const GameSettings *gameSettings) { return bOkToStart; } -void ServerInterface::broadcastGameSetup(const GameSettings *gameSettings) { +void ServerInterface::broadcastGameSetup(GameSettings *gameSettingsBuffer, bool setGameSettingsBuffer) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); + if(setGameSettingsBuffer == true) { + validateGameSettings(gameSettingsBuffer); + //setGameSettings(gameSettingsBuffer,false); + MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); + gameSettings = *gameSettingsBuffer; + gameSettingsUpdateCount++; + } MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); - NetworkMessageLaunch networkMessageLaunch(gameSettings, nmtBroadCastSetup); + NetworkMessageLaunch networkMessageLaunch(gameSettingsBuffer, nmtBroadCastSetup); broadcastMessage(&networkMessageLaunch); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d\n",__FILE__,__FUNCTION__,__LINE__); } @@ -1833,40 +1840,70 @@ int ServerInterface::getOpenSlotCount() { } int ServerInterface::getGameSettingsUpdateCount() { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount); MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount); int result = gameSettingsUpdateCount; safeMutex.ReleaseLock(); return result; } -void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount,waitForClientAck); +void ServerInterface::validateGameSettings(GameSettings *serverGameSettings) { MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s]\n",__FILE__,__FUNCTION__); + + string mapFile = serverGameSettings->getMap(); + if(find(mapFiles.begin(),mapFiles.end(),mapFile) == mapFiles.end()) { + printf("Reverting map from [%s] to [%s]\n",serverGameSettings->getMap().c_str(),gameSettings.getMap().c_str()); + + serverGameSettings->setMapFilterIndex(gameSettings.getMapFilterIndex()); + serverGameSettings->setMap(gameSettings.getMap()); + serverGameSettings->setMapCRC(gameSettings.getMapCRC()); + } + + string tilesetFile = serverGameSettings->getTileset(); + if(find(tilesetFiles.begin(),tilesetFiles.end(),tilesetFile) == tilesetFiles.end()) { + printf("Reverting tileset from [%s] to [%s]\n",serverGameSettings->getTileset().c_str(),gameSettings.getTileset().c_str()); + + serverGameSettings->setTileset(gameSettings.getTileset()); + serverGameSettings->setTilesetCRC(gameSettings.getTilesetCRC()); + } + + string techtreeFile = serverGameSettings->getTech(); + if(find(techTreeFiles.begin(),techTreeFiles.end(),techtreeFile) == techTreeFiles.end()) { + printf("Reverting tech from [%s] to [%s]\n",serverGameSettings->getTech().c_str(),gameSettings.getTech().c_str()); + + serverGameSettings->setTech(gameSettings.getTech()); + serverGameSettings->setTechCRC(gameSettings.getTechCRC()); + } +} + +void ServerInterface::setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck) { + MutexSafeWrapper safeMutex(serverSynchAccessor,CODE_AT_LINE); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] START gameSettingsUpdateCount = %d, waitForClientAck = %d\n",__FILE__,__FUNCTION__,gameSettingsUpdateCount,waitForClientAck); if(serverGameSettings->getScenario() == "") { string mapFile = serverGameSettings->getMap(); if(find(mapFiles.begin(),mapFiles.end(),mapFile) == mapFiles.end()) { printf("Reverting map from [%s] to [%s]\n",serverGameSettings->getMap().c_str(),gameSettings.getMap().c_str()); - + serverGameSettings->setMapFilterIndex(gameSettings.getMapFilterIndex()); serverGameSettings->setMap(gameSettings.getMap()); serverGameSettings->setMapCRC(gameSettings.getMapCRC()); } - + string tilesetFile = serverGameSettings->getTileset(); if(find(tilesetFiles.begin(),tilesetFiles.end(),tilesetFile) == tilesetFiles.end()) { printf("Reverting tileset from [%s] to [%s]\n",serverGameSettings->getTileset().c_str(),gameSettings.getTileset().c_str()); - + serverGameSettings->setTileset(gameSettings.getTileset()); serverGameSettings->setTilesetCRC(gameSettings.getTilesetCRC()); } - + string techtreeFile = serverGameSettings->getTech(); if(find(techTreeFiles.begin(),techTreeFiles.end(),techtreeFile) == techTreeFiles.end()) { printf("Reverting tech from [%s] to [%s]\n",serverGameSettings->getTech().c_str(),gameSettings.getTech().c_str()); - + serverGameSettings->setTech(gameSettings.getTech()); serverGameSettings->setTechCRC(gameSettings.getTechCRC()); } diff --git a/source/glest_game/network/server_interface.h b/source/glest_game/network/server_interface.h index fe28280e..ec48d5a9 100644 --- a/source/glest_game/network/server_interface.h +++ b/source/glest_game/network/server_interface.h @@ -124,8 +124,9 @@ public: int getConnectedSlotCount(); int getOpenSlotCount(); bool launchGame(const GameSettings *gameSettings); + void validateGameSettings(GameSettings *serverGameSettings); void setGameSettings(GameSettings *serverGameSettings, bool waitForClientAck); - void broadcastGameSetup(const GameSettings *gameSettings); + void broadcastGameSetup(GameSettings *gameSettingsBuffer, bool setGameSettingsBuffer=false); int getGameSettingsUpdateCount(); diff --git a/source/shared_lib/include/platform/posix/socket.h b/source/shared_lib/include/platform/posix/socket.h index de41b0f6..79d70721 100644 --- a/source/shared_lib/include/platform/posix/socket.h +++ b/source/shared_lib/include/platform/posix/socket.h @@ -253,7 +253,7 @@ public: virtual ~ServerSocket(); void bind(int port); void listen(int connectionQueueSize= SOMAXCONN); - Socket *accept(); + Socket *accept(bool errorOnFail=true); void stopBroadCastThread(); void pauseBroadcast(); diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index 14ea4026..80950ed6 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -768,7 +768,7 @@ bool Socket::isSocketValid() const { bool Socket::isSocketValid(const PLATFORM_SOCKET *validateSocket) { #ifdef WIN32 - if(validateSocket == NULL) { + if(validateSocket == NULL || (*validateSocket) == 0) { return false; } else { @@ -988,6 +988,7 @@ bool Socket::hasDataToRead(std::map &socketTriggeredList) fd_set rfds; FD_ZERO(&rfds); + string socketDebugList = ""; PLATFORM_SOCKET imaxsocket = 0; for(std::map::iterator itermap = socketTriggeredList.begin(); itermap != socketTriggeredList.end(); ++itermap) @@ -997,6 +998,11 @@ bool Socket::hasDataToRead(std::map &socketTriggeredList) { FD_SET(socket, &rfds); imaxsocket = max(socket,imaxsocket); + + if(socketDebugList != "") { + socketDebugList += ","; + } + socketDebugList += intToStr(socket); } } @@ -1015,7 +1021,7 @@ bool Socket::hasDataToRead(std::map &socketTriggeredList) } if(retval < 0) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] ERROR SELECTING SOCKET DATA retval = %d error = %s\n",__FILE__,__FUNCTION__,retval,getLastSocketErrorFormattedText().c_str()); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Line: %d, ERROR SELECTING SOCKET DATA retval = %d error = %s, socketDebugList [%s]\n",__FILE__,__FUNCTION__,__LINE__,retval,getLastSocketErrorFormattedText().c_str(),socketDebugList.c_str()); } else if(retval) { @@ -1150,7 +1156,8 @@ int Socket::getDataToRead(bool wantImmediateReply) { #else int err= ioctlsocket(sock, FIONREAD, &size); #endif - if(err < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN) + int lastSocketError = getLastSocketError(); + if(err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR PEEKING SOCKET DATA, err = %d %s\n",__FILE__,__FUNCTION__,__LINE__,err,getLastSocketErrorFormattedText().c_str()); break; @@ -1218,15 +1225,16 @@ int Socket::send(const void *data, int dataSize) { //bytesSent = -1; // END TEST - if(bytesSent < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR WRITING SOCKET DATA, err = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesSent,getLastSocketErrorFormattedText().c_str()); + int lastSocketError = getLastSocketError(); + if(bytesSent < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR WRITING SOCKET DATA, err = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesSent,getLastSocketErrorFormattedText(&lastSocketError).c_str()); } - else if(bytesSent < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN && isConnected() == true) { + else if(bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN && isConnected() == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 EAGAIN during send, trying again...\n",__FILE__,__FUNCTION__,__LINE__); int attemptCount = 0; time_t tStartTimer = time(NULL); - while((bytesSent < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) && + while((bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) && (difftime(time(NULL),tStartTimer) <= MAX_SEND_WAIT_SECONDS)) { attemptCount++; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount); @@ -1248,7 +1256,8 @@ int Socket::send(const void *data, int dataSize) { #else bytesSent = ::send(sock, (const char *)data, dataSize, MSG_NOSIGNAL | MSG_DONTWAIT); #endif - if(bytesSent < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN) { + lastSocketError = getLastSocketError(); + if(bytesSent < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { break; } @@ -1269,13 +1278,16 @@ int Socket::send(const void *data, int dataSize) { } if(isConnected() == true && bytesSent > 0 && bytesSent < dataSize) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] need to send more data, trying again getLastSocketError() = %d, bytesSent = %d, dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketError(),bytesSent,dataSize); + lastSocketError = getLastSocketError(); + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] need to send more data, trying again getLastSocketError() = %d, bytesSent = %d, dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,lastSocketError,bytesSent,dataSize); int totalBytesSent = bytesSent; int attemptCount = 0; + + time_t tStartTimer = time(NULL); while(((bytesSent > 0 && totalBytesSent < dataSize) || - (bytesSent < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN)) && + (bytesSent < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN)) && (difftime(time(NULL),tStartTimer) <= MAX_SEND_WAIT_SECONDS)) { attemptCount++; if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, totalBytesSent = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,totalBytesSent); @@ -1298,11 +1310,12 @@ int Socket::send(const void *data, int dataSize) { #else bytesSent = ::send(sock, &sendBuf[totalBytesSent], dataSize - totalBytesSent, MSG_NOSIGNAL | MSG_DONTWAIT); #endif + lastSocketError = getLastSocketError(); if(bytesSent > 0) { totalBytesSent += bytesSent; } - if(bytesSent < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN) { + if(bytesSent < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { break; } @@ -1362,14 +1375,15 @@ int Socket::receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet) { } safeMutex.ReleaseLock(); } - if(bytesReceived < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN) { - if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,getLastSocketErrorFormattedText().c_str()); + int lastSocketError = getLastSocketError(); + if(bytesReceived < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] ERROR READING SOCKET DATA error while sending socket data, bytesSent = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,getLastSocketErrorFormattedText(&lastSocketError).c_str()); } - else if(bytesReceived < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) { + else if(bytesReceived < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 EAGAIN during receive, trying again...\n",__FILE__,__FUNCTION__,__LINE__); time_t tStartTimer = time(NULL); - while((bytesReceived < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) && + while((bytesReceived < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) && (difftime(time(NULL),tStartTimer) <= MAX_RECV_WAIT_SECONDS)) { if(isConnected() == false) { int iErr = getLastSocketError(); @@ -1389,6 +1403,7 @@ int Socket::receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet) { MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); bytesReceived = recv(sock, reinterpret_cast(data), dataSize, 0); + lastSocketError = getLastSocketError(); safeMutex.ReleaseLock(); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 EAGAIN during receive, trying again returned: %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived); @@ -1460,17 +1475,18 @@ int Socket::peek(void *data, int dataSize,bool mustGetData) { } //if(chrono.getMillis() > 1) printf("In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); - if(err < 0 && getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN) { + int lastSocketError = getLastSocketError(); + if(err < 0 && lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] ERROR PEEKING SOCKET DATA error while sending socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,err,getLastSocketErrorFormattedText().c_str()); disconnectSocket(); } - else if(err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN && mustGetData == true) { + else if(err < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN && mustGetData == true) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #1 ERROR EAGAIN during peek, trying again...\n",__FILE__,__FUNCTION__,__LINE__); //printf("Peek #2 err = %d\n",err); time_t tStartTimer = time(NULL); - while((err < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) && + while((err < 0 && lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) && (difftime(time(NULL),tStartTimer) <= MAX_PEEK_WAIT_SECONDS)) { /* if(isConnected() == false) { @@ -1492,6 +1508,7 @@ int Socket::peek(void *data, int dataSize,bool mustGetData) { //MutexSafeWrapper safeMutex(&dataSynchAccessor,CODE_AT_LINE + "_" + intToStr(sock) + "_" + intToStr(dataSize)); MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); err = recv(sock, reinterpret_cast(data), dataSize, MSG_PEEK); + lastSocketError = getLastSocketError(); safeMutex.ReleaseLock(); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) if(chrono.getMillis() > 1) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] action running for msecs: %lld\n",__FILE__,__FUNCTION__,__LINE__,(long long int)chrono.getMillis()); @@ -1506,8 +1523,9 @@ int Socket::peek(void *data, int dataSize,bool mustGetData) { if(err <= 0) { //printf("Peek #3 err = %d\n",err); - if(mustGetData == true || getLastSocketError() != PLATFORM_SOCKET_TRY_AGAIN) { - int iErr = getLastSocketError(); + lastSocketError = getLastSocketError(); + if(mustGetData == true || lastSocketError != PLATFORM_SOCKET_TRY_AGAIN) { + int iErr = lastSocketError; disconnectSocket(); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTED SOCKET error while peeking socket data, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,err,getLastSocketErrorFormattedText(&iErr).c_str()); @@ -1769,8 +1787,9 @@ void ClientSocket::connect(const Ip &ip, int port) if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,ip.getString().c_str(),port,err,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n",__FILE__,__FUNCTION__,__LINE__,ip.getString().c_str(),port,err,getLastSocketErrorFormattedText().c_str()); - if (getLastSocketError() == PLATFORM_SOCKET_INPROGRESS || - getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) { + int lastSocketError = getLastSocketError(); + if (lastSocketError == PLATFORM_SOCKET_INPROGRESS || + lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) { fd_set myset; struct timeval tv; int valopt=0; @@ -1789,10 +1808,11 @@ void ClientSocket::connect(const Ip &ip, int port) { MutexSafeWrapper safeMutex(dataSynchAccessorRead,CODE_AT_LINE); err = select((int)sock + 1, NULL, &myset, NULL, &tv); + lastSocketError = getLastSocketError(); //safeMutex.ReleaseLock(); } - if (err < 0 && getLastSocketError() != PLATFORM_SOCKET_INTERRUPTED) { + if (err < 0 && lastSocketError != PLATFORM_SOCKET_INTERRUPTED) { if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Error connecting %s\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error connecting %s\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketErrorFormattedText().c_str()); @@ -2197,9 +2217,14 @@ void ServerSocket::listen(int connectionQueueSize) { } } -Socket *ServerSocket::accept() { +Socket *ServerSocket::accept(bool errorOnFail) { if(isSocketValid() == false) { - throwException("socket is invalid!"); + if(errorOnFail == true) { + throwException("socket is invalid!"); + } + else { + return NULL; + } } struct sockaddr_in cli_addr; @@ -2214,11 +2239,16 @@ Socket *ServerSocket::accept() { sprintf(szBuf, "In [%s::%s Line: %d] Error accepting socket connection sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,newSock,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] %s\n",__FILE__,__FUNCTION__,__LINE__,szBuf); - if(getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) - { + int lastSocketError = getLastSocketError(); + if(lastSocketError == PLATFORM_SOCKET_TRY_AGAIN) { + return NULL; + } + if(errorOnFail == true) { + throwException(szBuf); + } + else { return NULL; } - throwException(szBuf); } else {