- attempt to fix socket bug where we incorrectly polled for data using ioctl / ioctlsocket. While we stilkl do some peeks, the bulk of the socket work is now done properly by simply doing recv and thus should prove more stable and reliable as well as perform better.

This commit is contained in:
Mark Vejvoda 2011-04-24 04:22:19 +00:00
parent fa82d1712a
commit ac83b1a898
7 changed files with 218 additions and 61 deletions

View File

@ -660,6 +660,7 @@ void ClientInterface::waitUntilReady(Checksum* checksum) {
// FOR TESTING ONLY - delay to see the client count up while waiting // FOR TESTING ONLY - delay to see the client count up while waiting
//sleep(5000); //sleep(5000);
//clientSocket->setBlock(true);
//send ready message //send ready message
NetworkMessageReady networkMessageReady; NetworkMessageReady networkMessageReady;
sendMessage(&networkMessageReady); sendMessage(&networkMessageReady);

View File

@ -184,7 +184,7 @@ void FileTransferSocketThread::execute()
char data[513]=""; char data[513]="";
memset(data, 0, 256); memset(data, 0, 256);
clientSocket->receive(data,256); clientSocket->receive(data,256, true);
if(*data == SEND_FILE) if(*data == SEND_FILE)
{ {
FileInfo file; FileInfo file;
@ -209,7 +209,7 @@ void FileTransferSocketThread::execute()
memcpy(data+1,&file,sizeof(file)); memcpy(data+1,&file,sizeof(file));
clientSocket->send(data,256); clientSocket->send(data,256);
clientSocket->receive(data,256); clientSocket->receive(data,256, true);
if(*data != ACK) { if(*data != ACK) {
//transfer error //transfer error
} }
@ -225,7 +225,7 @@ void FileTransferSocketThread::execute()
//if(written!=pack) //if(written!=pack)
// ; //read error // ; //read error
clientSocket->send(data,512); clientSocket->send(data,512);
clientSocket->receive(data,256); clientSocket->receive(data,256, true);
if(*data!=ACK) { if(*data!=ACK) {
//transfer error //transfer error
} }
@ -238,7 +238,7 @@ void FileTransferSocketThread::execute()
// ; //read error // ; //read error
clientSocket->send(data,remain); clientSocket->send(data,remain);
clientSocket->receive(data,256); clientSocket->receive(data,256, true);
if(*data!=ACK) { if(*data!=ACK) {
//transfer error //transfer error
} }
@ -274,12 +274,12 @@ void FileTransferSocketThread::execute()
memcpy(data+1,&file,sizeof(file)); memcpy(data+1,&file,sizeof(file));
clientSocket.send(data,256); clientSocket.send(data,256);
clientSocket.receive(data,256); clientSocket.receive(data,256, true);
if(*data!=ACK) { if(*data!=ACK) {
//transfer error //transfer error
} }
clientSocket.receive(data,256); clientSocket.receive(data,256,true);
if(*data == SEND_FILE) if(*data == SEND_FILE)
{ {
memcpy(&file, data+1, sizeof(file)); memcpy(&file, data+1, sizeof(file));
@ -291,7 +291,7 @@ void FileTransferSocketThread::execute()
while(packs--) while(packs--)
{ {
clientSocket.receive(data,512); clientSocket.receive(data,512,true);
outFile.write(data, 512); outFile.write(data, 512);
if(outFile.bad()) if(outFile.bad())
@ -305,7 +305,7 @@ void FileTransferSocketThread::execute()
*data=ACK; *data=ACK;
clientSocket.send(data,256); clientSocket.send(data,256);
} }
clientSocket.receive(data,remain); clientSocket.receive(data,remain,true);
outFile.write(data, remain); outFile.write(data, remain);
if(outFile.bad()) if(outFile.bad())

View File

@ -109,7 +109,7 @@ ServerInterface* NetworkManager::getServerInterface(bool throwErrorOnNull) {
} }
ClientInterface* NetworkManager::getClientInterface(bool throwErrorOnNull) { ClientInterface* NetworkManager::getClientInterface(bool throwErrorOnNull) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface); //if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] this->networkRole = %d gameNetworkInterface [%p]\n",__FILE__,__FUNCTION__,__LINE__,this->networkRole,gameNetworkInterface);
if(throwErrorOnNull) { if(throwErrorOnNull) {
assert(gameNetworkInterface!=NULL); assert(gameNetworkInterface!=NULL);

View File

@ -37,6 +37,7 @@ namespace Glest{ namespace Game{
// class NetworkMessage // class NetworkMessage
// ===================================================== // =====================================================
/*
bool NetworkMessage::peek(Socket* socket, void* data, int dataSize) { bool NetworkMessage::peek(Socket* socket, void* data, int dataSize) {
if(socket != NULL) { if(socket != NULL) {
int ipeekdatalen = socket->getDataToRead(); int ipeekdatalen = socket->getDataToRead();
@ -60,8 +61,10 @@ bool NetworkMessage::peek(Socket* socket, void* data, int dataSize) {
} }
return false; return false;
} }
*/
bool NetworkMessage::receive(Socket* socket, void* data, int dataSize) { bool NetworkMessage::receive(Socket* socket, void* data, int dataSize, bool tryReceiveUntilDataSizeMet) {
/*
if(socket != NULL) { if(socket != NULL) {
int ipeekdatalen = socket->getDataToRead(); int ipeekdatalen = socket->getDataToRead();
if(ipeekdatalen >= dataSize) { if(ipeekdatalen >= dataSize) {
@ -83,6 +86,25 @@ bool NetworkMessage::receive(Socket* socket, void* data, int dataSize) {
} }
} }
return false; return false;
*/
if(socket != NULL) {
int dataReceived = socket->receive(data, dataSize, tryReceiveUntilDataSizeMet);
if(dataReceived != dataSize) {
if(socket != NULL && socket->getSocketId() > 0) {
throw runtime_error("Error receiving NetworkMessage, dataReceived = " + intToStr(dataReceived) + ", dataSize = " + intToStr(dataSize));
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket has been disconnected\n",__FILE__,__FUNCTION__,__LINE__);
}
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] dataSize = %d, dataReceived = %d\n",__FILE__,__FUNCTION__,__LINE__,dataSize,dataReceived);
return true;
}
}
return false;
} }
void NetworkMessage::send(Socket* socket, const void* data, int dataSize) const { void NetworkMessage::send(Socket* socket, const void* data, int dataSize) const {
@ -133,7 +155,7 @@ NetworkMessageIntro::NetworkMessageIntro(int32 sessionId,const string &versionSt
} }
bool NetworkMessageIntro::receive(Socket* socket) { bool NetworkMessageIntro::receive(Socket* socket) {
bool result = NetworkMessage::receive(socket, &data, sizeof(data)); bool result = NetworkMessage::receive(socket, &data, sizeof(data), true);
data.name.nullTerminate(); data.name.nullTerminate();
data.versionString.nullTerminate(); data.versionString.nullTerminate();
data.language.nullTerminate(); data.language.nullTerminate();
@ -164,7 +186,7 @@ NetworkMessagePing::NetworkMessagePing(int32 pingFrequency, int64 pingTime){
} }
bool NetworkMessagePing::receive(Socket* socket){ bool NetworkMessagePing::receive(Socket* socket){
bool result = NetworkMessage::receive(socket, &data, sizeof(data)); bool result = NetworkMessage::receive(socket, &data, sizeof(data), true);
pingReceivedLocalTime = time(NULL); pingReceivedLocalTime = time(NULL);
return result; return result;
} }
@ -189,7 +211,7 @@ NetworkMessageReady::NetworkMessageReady(int32 checksum) {
} }
bool NetworkMessageReady::receive(Socket* socket){ bool NetworkMessageReady::receive(Socket* socket){
return NetworkMessage::receive(socket, &data, sizeof(data)); return NetworkMessage::receive(socket, &data, sizeof(data), true);
} }
void NetworkMessageReady::send(Socket* socket) const { void NetworkMessageReady::send(Socket* socket) const {
@ -314,7 +336,7 @@ vector<pair<string,int32> > NetworkMessageLaunch::getFactionCRCList() const {
} }
bool NetworkMessageLaunch::receive(Socket* socket) { bool NetworkMessageLaunch::receive(Socket* socket) {
bool result = NetworkMessage::receive(socket, &data, sizeof(data)); bool result = NetworkMessage::receive(socket, &data, sizeof(data), true);
data.description.nullTerminate(); data.description.nullTerminate();
data.map.nullTerminate(); data.map.nullTerminate();
data.tileset.nullTerminate(); data.tileset.nullTerminate();
@ -367,8 +389,9 @@ bool NetworkMessageCommandList::addCommand(const NetworkCommand* networkCommand)
bool NetworkMessageCommandList::receive(Socket* socket) { bool NetworkMessageCommandList::receive(Socket* socket) {
// _peek_ type, commandCount & frame num first. // _peek_ type, commandCount & frame num first.
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d]\n",__FILE__,__FUNCTION__,__LINE__);
const double MAX_MSG_WAIT_SECONDS = 3;
/*
const double MAX_MSG_WAIT_SECONDS = 3;
// Wait a max of x seconds for this message // Wait a max of x seconds for this message
for(time_t elapsedWait = time(NULL); difftime(time(NULL),elapsedWait) <= MAX_MSG_WAIT_SECONDS;) { for(time_t elapsedWait = time(NULL); difftime(time(NULL),elapsedWait) <= MAX_MSG_WAIT_SECONDS;) {
if (NetworkMessage::peek(socket, &data, commandListHeaderSize) == true) { if (NetworkMessage::peek(socket, &data, commandListHeaderSize) == true) {
@ -416,6 +439,38 @@ bool NetworkMessageCommandList::receive(Socket* socket) {
} }
} }
return result; return result;
*/
bool result = NetworkMessage::receive(socket, &data.header, commandListHeaderSize, true);
if(result == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] got header, messageType = %d, commandCount = %u, frameCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.commandCount,data.header.frameCount);
// read header + data.commandCount commands.
//int totalMsgSize = commandListHeaderSize + (sizeof(NetworkCommand) * data.header.commandCount);
if(data.header.commandCount > 0) {
int totalMsgSize = (sizeof(NetworkCommand) * data.header.commandCount);
result = NetworkMessage::receive(socket, &data.commands, totalMsgSize, true);
if(result == true) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled == true) {
for(int idx = 0 ; idx < data.header.commandCount; ++idx) {
const NetworkCommand &cmd = data.commands[idx];
SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] index = %d, received networkCommand [%s]\n",
__FILE__,__FUNCTION__,__LINE__,idx, cmd.toString().c_str());
}
}
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR Failed to get command data, totalMsgSize = %d.\n",__FILE__,__FUNCTION__,__LINE__,totalMsgSize);
}
}
}
else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] ERROR header not received as expected\n",__FILE__,__FUNCTION__,__LINE__);
SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] ERROR header not received as expected\n",__FILE__,__FUNCTION__,__LINE__);
}
return result;
} }
void NetworkMessageCommandList::send(Socket* socket) const { void NetworkMessageCommandList::send(Socket* socket) const {
@ -466,7 +521,7 @@ NetworkMessageText * NetworkMessageText::getCopy() const {
} }
bool NetworkMessageText::receive(Socket* socket){ bool NetworkMessageText::receive(Socket* socket){
bool result = NetworkMessage::receive(socket, &data, sizeof(data)); bool result = NetworkMessage::receive(socket, &data, sizeof(data), true);
data.text.nullTerminate(); data.text.nullTerminate();
data.targetLanguage.nullTerminate(); data.targetLanguage.nullTerminate();
@ -490,7 +545,7 @@ NetworkMessageQuit::NetworkMessageQuit(){
} }
bool NetworkMessageQuit::receive(Socket* socket){ bool NetworkMessageQuit::receive(Socket* socket){
return NetworkMessage::receive(socket, &data, sizeof(data)); return NetworkMessage::receive(socket, &data, sizeof(data),true);
} }
void NetworkMessageQuit::send(Socket* socket) const{ void NetworkMessageQuit::send(Socket* socket) const{
@ -618,6 +673,7 @@ string NetworkMessageSynchNetworkGameData::getTechCRCFileMismatchReport(vector<s
bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) { bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to get nmtSynchNetworkGameData\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to get nmtSynchNetworkGameData\n",__FILE__,__FUNCTION__,__LINE__);
/*
data.header.techCRCFileCount = 0; data.header.techCRCFileCount = 0;
const double MAX_MSG_WAIT_SECONDS = 10; const double MAX_MSG_WAIT_SECONDS = 10;
@ -640,7 +696,7 @@ bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.techCRCFileCount); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.techCRCFileCount);
bool result = NetworkMessage::receive(socket, &data, HeaderSize); bool result = NetworkMessage::receive(socket, &data, HeaderSize, true);
if(result == true && data.header.techCRCFileCount > 0) { if(result == true && data.header.techCRCFileCount > 0) {
// Here we loop possibly multiple times // Here we loop possibly multiple times
@ -671,7 +727,7 @@ bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) {
} }
} }
result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], packetDetail1DataSize); result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], packetDetail1DataSize, true);
if(result == true) { if(result == true) {
for(int i = 0; i < data.header.techCRCFileCount; ++i) { for(int i = 0; i < data.header.techCRCFileCount; ++i) {
data.detail.techCRCFileList[i].nullTerminate(); data.detail.techCRCFileList[i].nullTerminate();
@ -684,13 +740,61 @@ bool NetworkMessageSynchNetworkGameData::receive(Socket* socket) {
} }
} }
result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], packetDetail2DataSize); result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], packetDetail2DataSize, true);
} }
} }
} }
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result);
return result; return result;
*/
data.header.techCRCFileCount = 0;
bool result = NetworkMessage::receive(socket, &data, HeaderSize, true);
if(result == true && data.header.techCRCFileCount > 0) {
data.header.map.nullTerminate();
data.header.tileset.nullTerminate();
data.header.tech.nullTerminate();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.techCRCFileCount);
// Here we loop possibly multiple times
int packetLoopCount = 1;
if(data.header.techCRCFileCount > NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount) {
packetLoopCount = (data.header.techCRCFileCount / NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount);
if(data.header.techCRCFileCount % NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount > 0) {
packetLoopCount++;
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] packetLoopCount = %d\n",__FILE__,__FUNCTION__,__LINE__,packetLoopCount);
for(int iPacketLoop = 0; result == true && iPacketLoop < packetLoopCount; ++iPacketLoop) {
int packetIndex = iPacketLoop * NetworkMessageSynchNetworkGameData::maxFileCRCPacketCount;
int maxFileCountPerPacket = maxFileCRCPacketCount;
int packetFileCount = min(maxFileCountPerPacket,data.header.techCRCFileCount - packetIndex);
int packetDetail1DataSize = (DetailSize1 * packetFileCount);
int packetDetail2DataSize = (DetailSize2 * packetFileCount);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] iPacketLoop = %d, packetIndex = %d, maxFileCountPerPacket = %d, packetFileCount = %d, packetDetail1DataSize = %d, packetDetail2DataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,iPacketLoop,packetIndex,maxFileCountPerPacket,packetFileCount,packetDetail1DataSize,packetDetail2DataSize);
// Wait a max of x seconds for this message
result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], packetDetail1DataSize, true);
if(result == true) {
for(int i = 0; i < data.header.techCRCFileCount; ++i) {
data.detail.techCRCFileList[i].nullTerminate();
}
result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], packetDetail2DataSize, true);
}
}
}
return result;
} }
void NetworkMessageSynchNetworkGameData::send(Socket* socket) const { void NetworkMessageSynchNetworkGameData::send(Socket* socket) const {
@ -801,6 +905,8 @@ string NetworkMessageSynchNetworkGameDataStatus::getTechCRCFileMismatchReport(st
bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) { bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to get nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__,__LINE__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] about to get nmtSynchNetworkGameDataStatus\n",__FILE__,__FUNCTION__,__LINE__);
/*
data.header.techCRCFileCount = 0; data.header.techCRCFileCount = 0;
const double MAX_MSG_WAIT_SECONDS = 3; const double MAX_MSG_WAIT_SECONDS = 3;
@ -819,7 +925,7 @@ bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.techCRCFileCount); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] messageType = %d, data.techCRCFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,data.header.messageType,data.header.techCRCFileCount);
bool result = NetworkMessage::receive(socket, &data, HeaderSize); bool result = NetworkMessage::receive(socket, &data, HeaderSize, true);
if(result == true && data.header.techCRCFileCount > 0) { if(result == true && data.header.techCRCFileCount > 0) {
// Here we loop possibly multiple times // Here we loop possibly multiple times
int packetLoopCount = 1; int packetLoopCount = 1;
@ -847,7 +953,7 @@ bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) {
} }
} }
result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount)); result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount),true);
if(result == true) { if(result == true) {
for(int i = 0; i < data.header.techCRCFileCount; ++i) { for(int i = 0; i < data.header.techCRCFileCount; ++i) {
data.detail.techCRCFileList[i].nullTerminate(); data.detail.techCRCFileList[i].nullTerminate();
@ -860,7 +966,47 @@ bool NetworkMessageSynchNetworkGameDataStatus::receive(Socket* socket) {
} }
} }
result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount)); result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount),true);
}
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] result = %d\n",__FILE__,__FUNCTION__,__LINE__,result);
return result;
*/
data.header.techCRCFileCount = 0;
bool result = NetworkMessage::receive(socket, &data, HeaderSize, true);
if(result == true && data.header.techCRCFileCount > 0) {
// Here we loop possibly multiple times
int packetLoopCount = 1;
if(data.header.techCRCFileCount > NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount) {
packetLoopCount = (data.header.techCRCFileCount / NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount);
if(data.header.techCRCFileCount % NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount > 0) {
packetLoopCount++;
}
}
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) 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 * NetworkMessageSynchNetworkGameDataStatus::maxFileCRCPacketCount;
int maxFileCountPerPacket = maxFileCRCPacketCount;
int packetFileCount = min(maxFileCountPerPacket,data.header.techCRCFileCount - packetIndex);
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] iPacketLoop = %d, packetIndex = %d, packetFileCount = %d\n",__FILE__,__FUNCTION__,__LINE__,iPacketLoop,packetIndex,packetFileCount);
result = NetworkMessage::receive(socket, &data.detail.techCRCFileList[packetIndex], (DetailSize1 * packetFileCount),true);
if(result == true) {
for(int i = 0; i < data.header.techCRCFileCount; ++i) {
data.detail.techCRCFileList[i].nullTerminate();
}
// Wait a max of x seconds for this message
result = NetworkMessage::receive(socket, &data.detail.techCRCFileCRCList[packetIndex], (DetailSize2 * packetFileCount),true);
} }
} }
} }
@ -916,7 +1062,7 @@ NetworkMessageSynchNetworkGameDataFileCRCCheck::NetworkMessageSynchNetworkGameDa
} }
bool NetworkMessageSynchNetworkGameDataFileCRCCheck::receive(Socket* socket) { bool NetworkMessageSynchNetworkGameDataFileCRCCheck::receive(Socket* socket) {
bool result = NetworkMessage::receive(socket, &data, sizeof(data)); bool result = NetworkMessage::receive(socket, &data, sizeof(data), true);
data.fileName.nullTerminate(); data.fileName.nullTerminate();
@ -942,7 +1088,7 @@ NetworkMessageSynchNetworkGameDataFileGet::NetworkMessageSynchNetworkGameDataFil
} }
bool NetworkMessageSynchNetworkGameDataFileGet::receive(Socket* socket) { bool NetworkMessageSynchNetworkGameDataFileGet::receive(Socket* socket) {
bool result = NetworkMessage::receive(socket, &data, sizeof(data)); bool result = NetworkMessage::receive(socket, &data, sizeof(data), true);
data.fileName.nullTerminate(); data.fileName.nullTerminate();
@ -990,7 +1136,7 @@ SwitchSetupRequest::SwitchSetupRequest(string selectedFactionName, int8 currentF
} }
bool SwitchSetupRequest::receive(Socket* socket) { bool SwitchSetupRequest::receive(Socket* socket) {
bool result = NetworkMessage::receive(socket, &data, sizeof(data)); bool result = NetworkMessage::receive(socket, &data, sizeof(data), true);
data.selectedFactionName.nullTerminate(); data.selectedFactionName.nullTerminate();
data.networkPlayerName.nullTerminate(); data.networkPlayerName.nullTerminate();
@ -1018,13 +1164,11 @@ PlayerIndexMessage::PlayerIndexMessage(int16 playerIndex)
data.playerIndex=playerIndex; data.playerIndex=playerIndex;
} }
bool PlayerIndexMessage::receive(Socket* socket) bool PlayerIndexMessage::receive(Socket* socket) {
{ return NetworkMessage::receive(socket, &data, sizeof(data), true);
return NetworkMessage::receive(socket, &data, sizeof(data));
} }
void PlayerIndexMessage::send(Socket* socket) const void PlayerIndexMessage::send(Socket* socket) const {
{
assert(data.messageType==nmtPlayerIndexMessage); assert(data.messageType==nmtPlayerIndexMessage);
NetworkMessage::send(socket, &data, sizeof(data)); NetworkMessage::send(socket, &data, sizeof(data));
} }
@ -1038,9 +1182,8 @@ NetworkMessageLoadingStatus::NetworkMessageLoadingStatus(uint32 status)
data.status=status; data.status=status;
} }
bool NetworkMessageLoadingStatus::receive(Socket* socket) bool NetworkMessageLoadingStatus::receive(Socket* socket) {
{ return NetworkMessage::receive(socket, &data, sizeof(data), true);
return NetworkMessage::receive(socket, &data, sizeof(data));
} }
void NetworkMessageLoadingStatus::send(Socket* socket) const void NetworkMessageLoadingStatus::send(Socket* socket) const

View File

@ -68,8 +68,8 @@ public:
virtual void send(Socket* socket) const = 0; virtual void send(Socket* socket) const = 0;
protected: protected:
bool peek(Socket* socket, void* data, int dataSize); //bool peek(Socket* socket, void* data, int dataSize);
bool receive(Socket* socket, void* data, int dataSize); bool receive(Socket* socket, void* data, int dataSize,bool tryReceiveUntilDataSizeMet);
void send(Socket* socket, const void* data, int dataSize) const; void send(Socket* socket, const void* data, int dataSize) const;
}; };

View File

@ -145,7 +145,7 @@ public:
int getDataToRead(bool wantImmediateReply=false); int getDataToRead(bool wantImmediateReply=false);
int send(const void *data, int dataSize); int send(const void *data, int dataSize);
int receive(void *data, int dataSize); int receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet);
int peek(void *data, int dataSize, bool mustGetData=true); int peek(void *data, int dataSize, bool mustGetData=true);
void setBlock(bool block); void setBlock(bool block);

View File

@ -1197,7 +1197,7 @@ int Socket::send(const void *data, int dataSize) {
return static_cast<int>(bytesSent); return static_cast<int>(bytesSent);
} }
int Socket::receive(void *data, int dataSize) { int Socket::receive(void *data, int dataSize, bool tryReceiveUntilDataSizeMet) {
const int MAX_RECV_WAIT_SECONDS = 3; const int MAX_RECV_WAIT_SECONDS = 3;
ssize_t bytesReceived = 0; ssize_t bytesReceived = 0;
@ -1251,7 +1251,19 @@ int Socket::receive(void *data, int dataSize) {
int iErr = getLastSocketError(); int iErr = getLastSocketError();
disconnectSocket(); disconnectSocket();
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,getLastSocketErrorFormattedText(&iErr).c_str()); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"[%s::%s Line: %d] DISCONNECTED SOCKET error while receiving socket data, bytesReceived = %d, error = %s, dataSize = %d, tryReceiveUntilDataSizeMet = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,getLastSocketErrorFormattedText(&iErr).c_str(),dataSize,tryReceiveUntilDataSizeMet);
}
else if(tryReceiveUntilDataSizeMet == true && bytesReceived < dataSize) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] WARNING, attempting to receive MORE data, bytesReceived = %d, dataSize = %d\n",__FILE__,__FUNCTION__,__LINE__,bytesReceived,dataSize);
char *dataAsCharPointer = reinterpret_cast<char *>(data);
int additionalBytes = receive(&dataAsCharPointer[bytesReceived], dataSize, tryReceiveUntilDataSizeMet);
if(additionalBytes > 0) {
bytesReceived += additionalBytes;
}
else {
throw runtime_error("additionalBytes == " + intToStr(additionalBytes));
}
} }
return static_cast<int>(bytesReceived); return static_cast<int>(bytesReceived);
} }
@ -1572,18 +1584,18 @@ void ClientSocket::connect(const Ip &ip, int port)
connectedIpAddress = ""; connectedIpAddress = "";
int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr)); int err= ::connect(sock, reinterpret_cast<const sockaddr*>(&addr), sizeof(addr));
if(err < 0) { if(err < 0) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n",__FILE__,__FUNCTION__,ip.getString().c_str(),port,err,getLastSocketErrorFormattedText().c_str()); 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] #2 Error connecting socket for IP: %s for Port: %d err = %d error = %s\n",__FILE__,__FUNCTION__,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 || if (getLastSocketError() == PLATFORM_SOCKET_INPROGRESS ||
getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) { getLastSocketError() == PLATFORM_SOCKET_TRY_AGAIN) {
fd_set myset; fd_set myset;
struct timeval tv; struct timeval tv;
int valopt; int valopt=0;
socklen_t lon; socklen_t lon=0;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__,__LINE__);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] PLATFORM_SOCKET_INPROGRESS in connect() - selecting\n",__FILE__,__FUNCTION__,__LINE__);
do { do {
tv.tv_sec = 10; tv.tv_sec = 10;
@ -1599,40 +1611,41 @@ void ClientSocket::connect(const Ip &ip, int port)
} }
if (err < 0 && getLastSocketError() != PLATFORM_SOCKET_INTERRUPTED) { if (err < 0 && getLastSocketError() != PLATFORM_SOCKET_INTERRUPTED) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Error connecting %s\n",__FILE__,__FUNCTION__,getLastSocketErrorFormattedText().c_str()); 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] Error connecting %s\n",__FILE__,__FUNCTION__,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error connecting %s\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketErrorFormattedText().c_str());
break; break;
} }
else if (err > 0) { else if(err > 0) {
//else if(FD_ISSET(sock, &myset)) {
// Socket selected for write // Socket selected for write
lon = sizeof(int); lon = sizeof(valopt);
#ifndef WIN32 #ifndef WIN32
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0) if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (void*)(&valopt), &lon) < 0)
#else #else
if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)(&valopt), &lon) < 0) if (getsockopt(sock, SOL_SOCKET, SO_ERROR, (char *)(&valopt), &lon) < 0)
#endif #endif
{ {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Error in getsockopt() %s\n",__FILE__,__FUNCTION__,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Error in getsockopt() %s\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketErrorFormattedText().c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Error in getsockopt() %s\n",__FILE__,__FUNCTION__,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error in getsockopt() %s\n",__FILE__,__FUNCTION__,__LINE__,getLastSocketErrorFormattedText().c_str());
break; break;
} }
// Check the value returned... // Check the value returned...
if(valopt) { if(valopt) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Error in delayed connection() %d - [%s]\n",__FILE__,__FUNCTION__,valopt, strerror(valopt)); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Error in delayed connection() %d - [%s]\n",__FILE__,__FUNCTION__,__LINE__,valopt, strerror(valopt));
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Error in delayed connection() %d - [%s]\n",__FILE__,__FUNCTION__,valopt, strerror(valopt)); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Error in delayed connection() %d - [%s]\n",__FILE__,__FUNCTION__,__LINE__,valopt, strerror(valopt));
break; break;
} }
errno = 0; errno = 0;
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Apparent recovery for connection sock = %d, err = %d\n",__FILE__,__FUNCTION__,sock,err); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Apparent recovery for connection sock = %d, err = %d\n",__FILE__,__FUNCTION__,__LINE__,sock,err);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Apparent recovery for connection sock = %d, err = %d\n",__FILE__,__FUNCTION__,sock,err); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Apparent recovery for connection sock = %d, err = %d\n",__FILE__,__FUNCTION__,__LINE__,sock,err);
break; break;
} }
else { else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Timeout in select() - Cancelling!\n",__FILE__,__FUNCTION__); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Timeout in select() - Cancelling!\n",__FILE__,__FUNCTION__,__LINE__);
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Timeout in select() - Cancelling!\n",__FILE__,__FUNCTION__); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Timeout in select() - Cancelling!\n",__FILE__,__FUNCTION__,__LINE__);
disconnectSocket(); disconnectSocket();
break; break;
@ -1641,13 +1654,13 @@ void ClientSocket::connect(const Ip &ip, int port)
} }
if(err < 0) { if(err < 0) {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Before END sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Before END sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,getLastSocketErrorFormattedText().c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Before END sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Before END sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,getLastSocketErrorFormattedText().c_str());
disconnectSocket(); disconnectSocket();
} }
else { else {
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s] Valid recovery for connection sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Valid recovery for connection sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,getLastSocketErrorFormattedText().c_str());
if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s] Valid recovery for connection sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,sock,err,getLastSocketErrorFormattedText().c_str()); if(SystemFlags::VERBOSE_MODE_ENABLED) printf("In [%s::%s Line: %d] Valid recovery for connection sock = %d, err = %d, error = %s\n",__FILE__,__FUNCTION__,__LINE__,sock,err,getLastSocketErrorFormattedText().c_str());
connectedIpAddress = ip.getString(); connectedIpAddress = ip.getString();
} }
} }