From e5678be10c335bb2d67bf488db8d30b76d1b86bd Mon Sep 17 00:00:00 2001 From: Mark Vejvoda Date: Thu, 26 Aug 2010 02:36:17 +0000 Subject: [PATCH] - bugfixes for experimental game data synch check in lobby - added a fix for socket sending when the send buffer is full and we have more data to send --- source/glest_game/network/network_message.cpp | 142 +++++++++++++----- source/glest_game/network/network_message.h | 10 +- .../sources/platform/posix/socket.cpp | 32 ++++ 3 files changed, 145 insertions(+), 39 deletions(-) diff --git a/source/glest_game/network/network_message.cpp b/source/glest_game/network/network_message.cpp index 3874abda..8df8d460 100644 --- a/source/glest_game/network/network_message.cpp +++ b/source/glest_game/network/network_message.cpp @@ -581,27 +581,27 @@ bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) { bool result = NetworkMessage::receive(socket, &data, HeaderSize); if(result == true && data.header.techCRCFileCount > 0) { - for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); - if (NetworkMessage::peek(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)) == true) { - break; - } - else { - sleep(1); // sleep 1 ms to wait for socket data + // Here we loop possibly multiple times + int packetLoopCount = 1; + if(data.header.techCRCFileCount > maxFileCRCPacketCount) { + packetLoopCount = (data.header.techCRCFileCount / maxFileCRCPacketCount); + if(data.header.techCRCFileCount % maxFileCRCPacketCount > 0) { + packetLoopCount++; } } - result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)); - if(result == true) { - for(int i = 0; i < data.header.techCRCFileCount; ++i) { - data.detail.techCRCFileList[i].nullTerminate(); - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] data.detail.techCRCFileList[i] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,data.detail.techCRCFileList[i].getString().c_str()); - } + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,packetLoopCount); + + for(int iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { + + int packetIndex = iPacketLoop * maxFileCRCPacketCount; + int packetFileCount = std::min(maxFileCRCPacketCount,data.header.techCRCFileCount - packetIndex); for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); - if (NetworkMessage::peek(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)) == true) { + + if (NetworkMessage::peek(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)) == true) { break; } else { @@ -609,7 +609,25 @@ bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) { } } - result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)); + result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)); + if(result == true) { + for(int i = 0; i < data.header.techCRCFileCount; ++i) { + data.detail.techCRCFileList[i].nullTerminate(); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] data.detail.techCRCFileList[i] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,data.detail.techCRCFileList[i].getString().c_str()); + } + + for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); + if (NetworkMessage::peek(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)) == true) { + break; + } + else { + sleep(1); // sleep 1 ms to wait for socket data + } + } + + result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)); + } } } @@ -623,8 +641,25 @@ void NetworkMessageSynchNetworkGameData::send(Socket* socket) const { assert(data.header.messageType==nmtSynchNetworkGameData); NetworkMessage::send(socket, &data, HeaderSize); if(data.header.techCRCFileCount > 0) { - NetworkMessage::send(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)); - NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)); + // Here we loop possibly multiple times + int packetLoopCount = 1; + if(data.header.techCRCFileCount > maxFileCRCPacketCount) { + packetLoopCount = (data.header.techCRCFileCount / maxFileCRCPacketCount); + if(data.header.techCRCFileCount % maxFileCRCPacketCount > 0) { + packetLoopCount++; + } + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,packetLoopCount); + + for(int iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { + + int packetIndex = iPacketLoop * maxFileCRCPacketCount; + int packetFileCount = std::min(maxFileCRCPacketCount,data.header.techCRCFileCount - packetIndex); + + NetworkMessage::send(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)); + NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)); + } } } @@ -721,28 +756,28 @@ bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) { bool result = NetworkMessage::receive(socket, &data, HeaderSize); if(result == true && data.header.techCRCFileCount > 0) { - for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { - SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); - - if (NetworkMessage::peek(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)) == true) { - break; - } - else { - sleep(1); // sleep 1 ms to wait for socket data + // Here we loop possibly multiple times + int packetLoopCount = 1; + if(data.header.techCRCFileCount > maxFileCRCPacketCount) { + packetLoopCount = (data.header.techCRCFileCount / maxFileCRCPacketCount); + if(data.header.techCRCFileCount % maxFileCRCPacketCount > 0) { + packetLoopCount++; } } - result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)); - if(result == true) { - for(int i = 0; i < data.header.techCRCFileCount; ++i) { - data.detail.techCRCFileList[i].nullTerminate(); - //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] data.detail.techCRCFileList[i] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,data.detail.techCRCFileList[i].getString().c_str()); - } + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,packetLoopCount); + + for(int iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { + + int packetIndex = iPacketLoop * maxFileCRCPacketCount; + int packetFileCount = std::min(maxFileCRCPacketCount,data.header.techCRCFileCount - packetIndex); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] iPacketLoop = %d, packetIndex = %d, packetFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,iPacketLoop,packetIndex,packetFileCount); for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); - if (NetworkMessage::peek(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)) == true) { + if (NetworkMessage::peek(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)) == true) { break; } else { @@ -750,7 +785,25 @@ bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) { } } - result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)); + result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)); + if(result == true) { + for(int i = 0; i < data.header.techCRCFileCount; ++i) { + data.detail.techCRCFileList[i].nullTerminate(); + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] data.detail.techCRCFileList[i] = [%s]\n",__FILE__,__FUNCTION__,__LINE__,data.detail.techCRCFileList[i].getString().c_str()); + } + + for(int peekAttempt = 1; peekAttempt < 5000; peekAttempt++) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] peekAttempt = %d\n",__FILE__,__FUNCTION__,__LINE__,peekAttempt); + if (NetworkMessage::peek(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)) == true) { + break; + } + else { + sleep(1); // sleep 1 ms to wait for socket data + } + } + + result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)); + } } } @@ -766,8 +819,27 @@ void NetworkMessageSynchNetworkGameDataStatus::send(Socket* socket) const { //int totalMsgSize = HeaderSize + (sizeof(DataDetail) * data.header.techCRCFileCount); NetworkMessage::send(socket, &data, HeaderSize); if(data.header.techCRCFileCount > 0) { - NetworkMessage::send(socket, &data.detail.techCRCFileList[0], (DetailSize1 * data.header.techCRCFileCount)); - NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[0], (DetailSize2 * data.header.techCRCFileCount)); + // Here we loop possibly multiple times + int packetLoopCount = 1; + if(data.header.techCRCFileCount > maxFileCRCPacketCount) { + packetLoopCount = (data.header.techCRCFileCount / maxFileCRCPacketCount); + if(data.header.techCRCFileCount % maxFileCRCPacketCount > 0) { + packetLoopCount++; + } + } + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,packetLoopCount); + + for(int iPacketLoop = 0; iPacketLoop < packetLoopCount; ++iPacketLoop) { + + int packetIndex = iPacketLoop * maxFileCRCPacketCount; + int packetFileCount = std::min(maxFileCRCPacketCount,data.header.techCRCFileCount - packetIndex); + + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoop = %d, packetIndex = %d, packetFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,iPacketLoop,packetIndex,packetFileCount); + + NetworkMessage::send(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)); + NetworkMessage::send(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)); + } } } diff --git a/source/glest_game/network/network_message.h b/source/glest_game/network/network_message.h index a2f68f2f..b28438a4 100644 --- a/source/glest_game/network/network_message.h +++ b/source/glest_game/network/network_message.h @@ -344,8 +344,9 @@ class NetworkMessageSynchNetworkGameData: public NetworkMessage{ private: -static const int maxStringSize= 200; -static const int maxFileCRCCount= 400; +static const int maxStringSize= 255; +static const int maxFileCRCCount= 5000; +static const int maxFileCRCPacketCount= 100; private: @@ -415,8 +416,9 @@ class NetworkMessageSynchNetworkGameDataStatus: public NetworkMessage{ private: -static const int maxStringSize= 100; -static const int maxFileCRCCount= 500; +static const int maxStringSize= 255; +static const int maxFileCRCCount= 5000; +static const int maxFileCRCPacketCount= 100; private: diff --git a/source/shared_lib/sources/platform/posix/socket.cpp b/source/shared_lib/sources/platform/posix/socket.cpp index 60c08447..c8346941 100644 --- a/source/shared_lib/sources/platform/posix/socket.cpp +++ b/source/shared_lib/sources/platform/posix/socket.cpp @@ -1019,6 +1019,38 @@ int Socket::send(const void *data, int dataSize) { } } + if(bytesSent > 0 && bytesSent < dataSize) { + 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); + + int totalBytesSent = bytesSent; + int attemptCount = 0; + time_t tStartTimer = time(NULL); + while(((bytesSent > 0 && totalBytesSent < dataSize) || + (bytesSent < 0 && getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN)) && + (difftime(time(NULL),tStartTimer) <= 5)) { + attemptCount++; + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, totalBytesSent = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,totalBytesSent); + + if(bytesSent > 0 || Socket::isWritable(true) == true) { + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d, sock = %d, dataSize = %d, data = %p\n",__FILE__,__FUNCTION__,__LINE__,attemptCount,sock,dataSize,data); + + MutexSafeWrapper safeMutex(&dataSynchAccessor); + const char *sendBuf = (const char *)data; + bytesSent = ::send(sock, &sendBuf[totalBytesSent], dataSize - totalBytesSent, MSG_NOSIGNAL); + + if(bytesSent > 0) { + totalBytesSent += bytesSent; + } + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] retry send returned: %d\n",__FILE__,__FUNCTION__,__LINE__,bytesSent); + } + SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] attemptCount = %d\n",__FILE__,__FUNCTION__,__LINE__,attemptCount); + } + + if(bytesSent > 0) { + bytesSent = totalBytesSent; + } + } + //SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(bytesSent <= 0) {