mirror of
https://github.com/glest/glest-source.git
synced 2025-02-24 11:42:31 +01:00
597 lines
22 KiB
C++
597 lines
22 KiB
C++
// ==============================================================
|
|
// This file is part of Glest (www.glest.org)
|
|
//
|
|
// Copyright (C) 2001-2008 Martiño Figueroa
|
|
//
|
|
// You can redistribute this code and/or modify it under
|
|
// the terms of the GNU General Public License as published
|
|
// by the Free Software Foundation; either version 2 of the
|
|
// License, or (at your option) any later version
|
|
// ==============================================================
|
|
|
|
#include "network_interface.h"
|
|
|
|
#include <exception>
|
|
#include <cassert>
|
|
|
|
#include "data_types.h"
|
|
#include "conversion.h"
|
|
#include "platform_util.h"
|
|
#include <fstream>
|
|
#include "util.h"
|
|
#include "network_protocol.h"
|
|
#include "leak_dumper.h"
|
|
|
|
using namespace Shared::Platform;
|
|
using namespace Shared::Util;
|
|
using namespace std;
|
|
|
|
namespace Glest{ namespace Game{
|
|
|
|
// =====================================================
|
|
// class NetworkInterface
|
|
// =====================================================
|
|
|
|
const int NetworkInterface::readyWaitTimeout= 99000; // 99 seconds to 0 looks good on the screen
|
|
|
|
bool NetworkInterface::allowGameDataSynchCheck = false;
|
|
bool NetworkInterface::allowDownloadDataSynch = false;
|
|
DisplayMessageFunction NetworkInterface::pCB_DisplayMessage = NULL;
|
|
|
|
Vec3f MarkedCell::static_system_marker_color(MAGENTA.x,MAGENTA.y,MAGENTA.z);
|
|
|
|
NetworkInterface::NetworkInterface() {
|
|
networkAccessMutex = new Mutex(CODE_AT_LINE);
|
|
|
|
networkGameDataSynchCheckOkMap=false;
|
|
networkGameDataSynchCheckOkTile=false;
|
|
networkGameDataSynchCheckOkTech=false;
|
|
receivedDataSynchCheck=false;
|
|
|
|
networkPlayerFactionCRCMutex = new Mutex(CODE_AT_LINE);
|
|
for(unsigned int index = 0; index < (unsigned int)GameConstants::maxPlayers; ++index) {
|
|
networkPlayerFactionCRC[index] = 0;
|
|
}
|
|
}
|
|
|
|
void NetworkInterface::init() {
|
|
networkAccessMutex = NULL;
|
|
|
|
networkGameDataSynchCheckOkMap=false;
|
|
networkGameDataSynchCheckOkTile=false;
|
|
networkGameDataSynchCheckOkTech=false;
|
|
receivedDataSynchCheck=false;
|
|
|
|
gameSettings = GameSettings();
|
|
|
|
networkPlayerFactionCRCMutex = NULL;
|
|
for(unsigned int index = 0; index < (unsigned int)GameConstants::maxPlayers; ++index) {
|
|
networkPlayerFactionCRC[index] = 0;
|
|
}
|
|
}
|
|
|
|
NetworkInterface::~NetworkInterface() {
|
|
delete networkAccessMutex;
|
|
networkAccessMutex = NULL;
|
|
|
|
delete networkPlayerFactionCRCMutex;
|
|
networkPlayerFactionCRCMutex = NULL;
|
|
}
|
|
|
|
uint32 NetworkInterface::getNetworkPlayerFactionCRC(int index) {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkPlayerFactionCRCMutex,mutexOwnerId);
|
|
|
|
return networkPlayerFactionCRC[index];
|
|
}
|
|
void NetworkInterface::setNetworkPlayerFactionCRC(int index, uint32 crc) {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkPlayerFactionCRCMutex,mutexOwnerId);
|
|
|
|
networkPlayerFactionCRC[index]=crc;
|
|
}
|
|
|
|
void NetworkInterface::addChatInfo(const ChatMsgInfo &msg) {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
chatTextList.push_back(msg);
|
|
}
|
|
|
|
void NetworkInterface::addMarkedCell(const MarkedCell &msg) {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
markedCellList.push_back(msg);
|
|
}
|
|
void NetworkInterface::addUnMarkedCell(const UnMarkedCell &msg) {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
unmarkedCellList.push_back(msg);
|
|
}
|
|
|
|
void NetworkInterface::sendMessage(NetworkMessage* networkMessage){
|
|
Socket* socket= getSocket(false);
|
|
|
|
networkMessage->send(socket);
|
|
}
|
|
|
|
NetworkMessageType NetworkInterface::getNextMessageType(int waitMilliseconds) {
|
|
Socket* socket= getSocket(false);
|
|
int8 messageType= nmtInvalid;
|
|
|
|
/*
|
|
if(socket != NULL &&
|
|
((waitMilliseconds <= 0 && socket->hasDataToRead() == true) ||
|
|
(waitMilliseconds > 0 && socket->hasDataToReadWithWait(waitMilliseconds) == true))) {
|
|
//peek message type
|
|
int dataSize = socket->getDataToRead();
|
|
if(dataSize >= (int)sizeof(messageType)) {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,dataSize);
|
|
|
|
int iPeek = socket->peek(&messageType, sizeof(messageType));
|
|
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,iPeek,messageType,sizeof(messageType));
|
|
}
|
|
else {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType,sizeof(messageType),dataSize);
|
|
}
|
|
|
|
//sanity check new message type
|
|
if(messageType < 0 || messageType >= nmtCount) {
|
|
if(getConnectHasHandshaked() == true) {
|
|
throw megaglest_runtime_error("Invalid message type: " + intToStr(messageType));
|
|
}
|
|
else {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Invalid message type = %d (no packet handshake yet so ignored)\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType);
|
|
}
|
|
}
|
|
}
|
|
|
|
return static_cast<NetworkMessageType>(messageType);
|
|
*/
|
|
|
|
|
|
// According to here: https://support.microsoft.com/en-us/kb/192599
|
|
// its a terrible sin to use MSG_PEEK so lets try an alternative
|
|
|
|
/*
|
|
int bytesReceived = socket->receive(&messageType, sizeof(messageType), true);
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,bytesReceived,messageType,sizeof(messageType));
|
|
|
|
return static_cast<NetworkMessageType>(messageType);
|
|
*/
|
|
|
|
|
|
if(socket != NULL &&
|
|
((waitMilliseconds <= 0 && socket->hasDataToRead() == true) ||
|
|
(waitMilliseconds > 0 && socket->hasDataToReadWithWait(waitMilliseconds) == true))) {
|
|
//peek message type
|
|
int dataSize = socket->getDataToRead();
|
|
if(dataSize >= (int)sizeof(messageType)) {
|
|
//if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,dataSize);
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] before recv\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__);
|
|
|
|
// int iPeek = socket->peek(&messageType, sizeof(messageType));
|
|
// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,iPeek,messageType,sizeof(messageType));
|
|
// if(iPeek > 0) {
|
|
int bytesReceived = socket->receive(&messageType, sizeof(messageType), true);
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] socket->getDataToRead() iPeek = %d, messageType = %d [size = %d]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,bytesReceived,messageType,sizeof(messageType));
|
|
//}
|
|
}
|
|
//else {
|
|
// if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] PEEK WARNING, socket->getDataToRead() messageType = %d [size = %d], dataSize = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType,sizeof(messageType),dataSize);
|
|
//}
|
|
|
|
if (socket->isSocketValid() == false) {
|
|
return nmtInvalid;
|
|
}
|
|
//sanity check new message type
|
|
if(messageType < 0 || messageType >= nmtCount) {
|
|
if(getConnectHasHandshaked() == true) {
|
|
throw megaglest_runtime_error("Invalid message type: " + intToStr(messageType));
|
|
}
|
|
else {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] Invalid message type = %d (no packet handshake yet so ignored)\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,messageType);
|
|
}
|
|
}
|
|
}
|
|
|
|
return static_cast<NetworkMessageType>(messageType);
|
|
|
|
}
|
|
|
|
bool NetworkInterface::receiveMessage(NetworkMessage* networkMessage){
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
|
|
|
|
Socket* socket= getSocket(false);
|
|
|
|
return networkMessage->receive(socket);
|
|
}
|
|
|
|
bool NetworkInterface::receiveMessage(NetworkMessage* networkMessage, NetworkMessageType type) {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__);
|
|
|
|
Socket* socket = getSocket(false);
|
|
|
|
return networkMessage->receive(socket, type);
|
|
}
|
|
|
|
bool NetworkInterface::isConnected(){
|
|
bool result = (getSocket()!=NULL && getSocket()->isConnected());
|
|
return result;
|
|
}
|
|
|
|
void NetworkInterface::setLastPingInfo(const NetworkMessagePing &ping) {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
this->lastPingInfo = ping;
|
|
}
|
|
|
|
void NetworkInterface::setLastPingInfoToNow() {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
this->lastPingInfo.setPingReceivedLocalTime(time(NULL));
|
|
}
|
|
|
|
NetworkMessagePing NetworkInterface::getLastPingInfo() {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
return lastPingInfo;
|
|
}
|
|
double NetworkInterface::getLastPingLag() {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
return difftime((long int)time(NULL),lastPingInfo.getPingReceivedLocalTime());
|
|
}
|
|
|
|
void NetworkInterface::DisplayErrorMessage(string sErr, bool closeSocket) {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] sErr [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sErr.c_str());
|
|
//SystemFlags::OutputDebug(SystemFlags::debugError,"In [%s::%s Line: %d] sErr [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sErr.c_str());
|
|
SystemFlags::OutputDebug(SystemFlags::debugSystem,"In [%s::%s Line: %d] sErr [%s]\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,sErr.c_str());
|
|
|
|
if(closeSocket == true && getSocket() != NULL) {
|
|
close();
|
|
}
|
|
|
|
if(pCB_DisplayMessage != NULL) {
|
|
pCB_DisplayMessage(sErr.c_str(), false);
|
|
}
|
|
else {
|
|
throw megaglest_runtime_error(sErr);
|
|
}
|
|
}
|
|
|
|
std::vector<ChatMsgInfo> NetworkInterface::getChatTextList(bool clearList) {
|
|
std::vector<ChatMsgInfo> result;
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
if(chatTextList.empty() == false) {
|
|
result = chatTextList;
|
|
|
|
if(clearList == true) {
|
|
chatTextList.clear();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void NetworkInterface::clearChatInfo() {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
if(chatTextList.empty() == false) {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] chatTextList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,chatTextList.size());
|
|
chatTextList.clear();
|
|
}
|
|
}
|
|
|
|
std::vector<MarkedCell> NetworkInterface::getMarkedCellList(bool clearList) {
|
|
std::vector<MarkedCell> result;
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
if(markedCellList.empty() == false) {
|
|
result = markedCellList;
|
|
|
|
if(clearList == true) {
|
|
markedCellList.clear();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void NetworkInterface::clearMarkedCellList() {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
if(markedCellList.empty() == false) {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] markedCellList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,markedCellList.size());
|
|
markedCellList.clear();
|
|
}
|
|
}
|
|
|
|
std::vector<UnMarkedCell> NetworkInterface::getUnMarkedCellList(bool clearList) {
|
|
std::vector<UnMarkedCell> result;
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
if(unmarkedCellList.empty() == false) {
|
|
result = unmarkedCellList;
|
|
|
|
if(clearList == true) {
|
|
unmarkedCellList.clear();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void NetworkInterface::clearUnMarkedCellList() {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
if(unmarkedCellList.empty() == false) {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] unmarkedCellList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,unmarkedCellList.size());
|
|
unmarkedCellList.clear();
|
|
}
|
|
}
|
|
|
|
std::vector<MarkedCell> NetworkInterface::getHighlightedCellList(bool clearList) {
|
|
std::vector<MarkedCell> result;
|
|
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
if(highlightedCellList.empty() == false) {
|
|
result = highlightedCellList;
|
|
|
|
if(clearList == true) {
|
|
highlightedCellList.clear();
|
|
}
|
|
}
|
|
return result;
|
|
}
|
|
|
|
void NetworkInterface::clearHighlightedCellList() {
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
if(highlightedCellList.empty() == false) {
|
|
if(SystemFlags::getSystemSettingType(SystemFlags::debugNetwork).enabled) SystemFlags::OutputDebug(SystemFlags::debugNetwork,"In [%s::%s Line: %d] markedCellList.size() = %d\n",extractFileFromDirectoryPath(__FILE__).c_str(),__FUNCTION__,__LINE__,markedCellList.size());
|
|
highlightedCellList.clear();
|
|
}
|
|
}
|
|
|
|
void NetworkInterface::setHighlightedCell(const MarkedCell &msg){
|
|
static string mutexOwnerId = string(__FILE__) + string("_") + intToStr(__LINE__);
|
|
MutexSafeWrapper safeMutex(networkAccessMutex,mutexOwnerId);
|
|
|
|
for(int idx = 0; idx < (int)highlightedCellList.size(); idx++) {
|
|
MarkedCell mc = highlightedCellList[idx];
|
|
if(mc.getFactionIndex()==msg.getFactionIndex()){
|
|
highlightedCellList.erase(highlightedCellList.begin()+ idx);
|
|
break;
|
|
}
|
|
}
|
|
highlightedCellList.push_back(msg);
|
|
}
|
|
|
|
float NetworkInterface::getThreadedPingMS(std::string host) {
|
|
float result = -1;
|
|
|
|
if(getSocket() != NULL) {
|
|
result = getSocket()->getThreadedPingMS(host);
|
|
}
|
|
return result;
|
|
}
|
|
|
|
// =====================================================
|
|
// class GameNetworkInterface
|
|
// =====================================================
|
|
|
|
GameNetworkInterface::GameNetworkInterface(){
|
|
quit= false;
|
|
}
|
|
|
|
void GameNetworkInterface::requestCommand(const NetworkCommand *networkCommand, bool insertAtStart) {
|
|
assert(networkCommand != NULL);
|
|
Mutex *mutex = getServerSynchAccessor();
|
|
|
|
if(insertAtStart == false) {
|
|
MutexSafeWrapper safeMutex(mutex,string(__FILE__) + "_" + intToStr(__LINE__));
|
|
requestedCommands.push_back(*networkCommand);
|
|
}
|
|
else {
|
|
MutexSafeWrapper safeMutex(mutex,string(__FILE__) + "_" + intToStr(__LINE__));
|
|
requestedCommands.insert(requestedCommands.begin(),*networkCommand);
|
|
}
|
|
}
|
|
|
|
// =====================================================
|
|
// class FileTransferSocketThread
|
|
// =====================================================
|
|
|
|
const int32 SEND_FILE = 0x20;
|
|
const int32 ACK = 0x47;
|
|
|
|
FileTransferSocketThread::FileTransferSocketThread(FileTransferInfo fileInfo) : info(fileInfo) {
|
|
this->info.serverPort += 100;
|
|
}
|
|
|
|
void FileTransferSocketThread::execute()
|
|
{
|
|
if(info.hostType == eServer)
|
|
{
|
|
ServerSocket serverSocket;
|
|
serverSocket.bind(this->info.serverPort);
|
|
serverSocket.listen(1);
|
|
Socket *clientSocket = serverSocket.accept();
|
|
|
|
char data[513]="";
|
|
memset(data, 0, 256);
|
|
|
|
clientSocket->receive(data,256, true);
|
|
if(*data == SEND_FILE)
|
|
{
|
|
FileInfo file;
|
|
|
|
memcpy(&file, data+1, sizeof(file));
|
|
|
|
*data=ACK;
|
|
clientSocket->send(data,256);
|
|
|
|
Checksum checksum;
|
|
checksum.addFile(file.fileName);
|
|
file.filecrc = checksum.getSum();
|
|
|
|
ifstream infile(file.fileName.c_str(), ios::in | ios::binary | ios::ate);
|
|
if(infile.is_open() == true)
|
|
{
|
|
file.filesize = infile.tellg();
|
|
infile.seekg (0, ios::beg);
|
|
|
|
memset(data, 0, 256);
|
|
*data=SEND_FILE;
|
|
memcpy(data+1,&file,sizeof(file));
|
|
|
|
clientSocket->send(data,256);
|
|
clientSocket->receive(data,256, true);
|
|
if(*data != ACK) {
|
|
//transfer error
|
|
}
|
|
|
|
int remain=file.filesize % 512 ;
|
|
int packs=(file.filesize-remain)/512;
|
|
|
|
while(packs--)
|
|
{
|
|
infile.read(data,512);
|
|
//if(!ReadFile(file,data,512,&read,NULL))
|
|
// ; //read error
|
|
//if(written!=pack)
|
|
// ; //read error
|
|
clientSocket->send(data,512);
|
|
clientSocket->receive(data,256, true);
|
|
if(*data!=ACK) {
|
|
//transfer error
|
|
}
|
|
}
|
|
|
|
infile.read(data,remain);
|
|
//if(!ReadFile(file,data,remain,&read,NULL))
|
|
// ; //read error
|
|
//if(written!=pack)
|
|
// ; //read error
|
|
|
|
clientSocket->send(data,remain);
|
|
clientSocket->receive(data,256, true);
|
|
if(*data!=ACK) {
|
|
//transfer error
|
|
}
|
|
|
|
infile.close();
|
|
}
|
|
}
|
|
|
|
delete clientSocket;
|
|
}
|
|
else
|
|
{
|
|
Ip ip(this->info.serverIP);
|
|
ClientSocket clientSocket;
|
|
clientSocket.connect(this->info.serverIP, this->info.serverPort);
|
|
|
|
if(clientSocket.isConnected() == true)
|
|
{
|
|
FileInfo file;
|
|
file.fileName = this->info.fileName;
|
|
//file.filesize =
|
|
//file.filecrc = this->info.
|
|
|
|
string path = extractDirectoryPathFromFile(file.fileName);
|
|
createDirectoryPaths(path);
|
|
ofstream outFile(file.fileName.c_str(), ios_base::binary | ios_base::out);
|
|
if(outFile.is_open() == true)
|
|
{
|
|
char data[513]="";
|
|
memset(data, 0, 256);
|
|
*data=SEND_FILE;
|
|
memcpy(data+1,&file,sizeof(file));
|
|
|
|
clientSocket.send(data,256);
|
|
clientSocket.receive(data,256, true);
|
|
if(*data!=ACK) {
|
|
//transfer error
|
|
}
|
|
|
|
clientSocket.receive(data,256,true);
|
|
if(*data == SEND_FILE)
|
|
{
|
|
memcpy(&file, data+1, sizeof(file));
|
|
*data=ACK;
|
|
clientSocket.send(data,256);
|
|
|
|
int remain = file.filesize % 512 ;
|
|
int packs = (file.filesize-remain) / 512;
|
|
|
|
while(packs--)
|
|
{
|
|
clientSocket.receive(data,512,true);
|
|
|
|
outFile.write(data, 512);
|
|
if(outFile.bad())
|
|
{
|
|
//int ii = 0;
|
|
}
|
|
//if(!WriteFile(file,data,512,&written,NULL))
|
|
// ; //write error
|
|
//if(written != pack)
|
|
// ; //write error
|
|
*data=ACK;
|
|
clientSocket.send(data,256);
|
|
}
|
|
clientSocket.receive(data,remain,true);
|
|
|
|
outFile.write(data, remain);
|
|
if(outFile.bad())
|
|
{
|
|
//int ii = 0;
|
|
}
|
|
|
|
//if(!WriteFile(file,data,remain,&written,NULL))
|
|
// ; //write error
|
|
//if(written!=pack)
|
|
// ; //write error
|
|
*data=ACK;
|
|
clientSocket.send(data,256);
|
|
|
|
Checksum checksum;
|
|
checksum.addFile(file.fileName);
|
|
uint32 crc = checksum.getSum();
|
|
if(file.filecrc != crc)
|
|
{
|
|
//int ii = 0;
|
|
}
|
|
|
|
//if(calc_crc(file)!=info.crc)
|
|
// ; //transfeer error
|
|
}
|
|
|
|
outFile.close();
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
}}//end namespace
|