Посылаю файл с клиента на сервер все вроде Ок доходит.
Во время приема файла сервер посылает посылку клиенту о том сколько сейчас он принял байт передаваемого файла.
И вот тут какая-то ерунда.
Посылаю клиенту информ посылку
Все хорошо посылка приходит.
И значение байт увеличивается(сервер отправляет) на стороне клиента, но когда дело доходит до 262144 - все дальше как будто ничего не происходит.
Хоя процесс передачи файла идет и переменная blockSize в коде сервера увеличивается.
Не могу понять что делаю не то ???
Подскажите пожалуйста.
Вот код сервера и клиента.
Код сервера
C++ (Qt)
//сервер
#define TYPE_INFO_FILE 1
#define TYPE_DATA_FILE 2
#define TYPE_COMMAND 3
#define TYPE_INFO_PROCESS 4
#define TYPE_PING 255
typedef struct{
int nFileSize;
char pFileName[max_char];
} sFileData;
typedef struct {
unsigned int sizePack;
unsigned short typePack;
unsigned int sizePack2;
} head_pack;
void ThreadServer::ParsDataRes()
{
static int blockSize = 0;
m_pTcpSocket->waitForReadyRead(1);
pData.append( m_pTcpSocket->readAll() );
while(pData.size() != 0)
{
if(pData.size() < sizeof(head_pack))
return ;
//m_iPingCounting = 0;
head_pack headPack;
memcpy((void*)(&headPack), (void *)(&pData.data()[0]), sizeof(head_pack));
if ( headPack.sizePack != headPack.sizePack2 )
{
pData = pData.mid( 1 );
continue;
}
//std::cout<<"headPack.typePack = "<<headPack.typePack<<"\n";
switch(headPack.typePack)
{
case TYPE_INFO_FILE:
if(headPack.sizePack + sizeof(head_pack) <= pData.size())
{
pData = pData.mid(sizeof(head_pack));
if( sizeof(sfiledata) <= headPack.sizePack ){
memcpy((char *)&sfiledata,&pData.data()[0],headPack.sizePack);
pData = pData.mid(headPack.sizePack);
}
else{
}
}
else{
return;
}
break;
case TYPE_DATA_FILE:
if(headPack.sizePack + sizeof(head_pack) <= pData.size())
{
pData = pData.mid(sizeof(head_pack));
QFile file;
file.write(&pData.data()[0],headPack.sizePack);
blockSize += headPack.sizePack;
pData = pData.mid(headPack.sizePack);
{// !!! формируем информ посылку и отправляем !!!
head_pack headpck;
headpck.sizePack = sizeof(int);
headpck.typePack = TYPE_INFO_PROCESS;
headpck.sizePack2 = sizeof(int);
QByteArray ba_progress;
ba_progress.append((char*)&headpck,sizeof(head_pack));
std::cout<<"blockSize = "<<blockSize;
ba_progress.append((char*)(&blockSize),sizeof(int));
m_pTcpSocket->write(ba_progress);
m_pTcpSocket->waitForBytesWritten(1);
}
if(sfiledata.nFileSize <= blockSize)
{
head_pack headpck;
headpck.sizePack = 1;
headpck.typePack = TYPE_COMMAND;
headpck.sizePack2 = 1;
QByteArray ba_success;
ba_success.append((char*)&headpck,sizeof(head_pack));
ba_success.append(CMD_SUCCESS_RECEIVE_FILE);
m_pTcpSocket->write(ba_success);
m_pTcpSocket->waitForBytesWritten(1);
blockSize = 0;
//std::cout<<"ôàéë óñïåøíî ïŵèíÿò\n";
}
}
else{
return;
}
break;
case TYPE_COMMAND:
break;
default:
pData = pData.mid( 1 );
continue;
};
}
return ;
}
Код клиента
C++ (Qt)
void ThreadClient::run()
{
m_pTcpSocket = new QTcpSocket();
m_pTcpSocket->connectToHost("127.0.0.1",80);
while( !m_bStopThread )
{
msleep(5);
ParsDataRes();
if(m_bSendFile) TransmiteFile();
}
}
void ThreadClient::ParsDataRes()
{
static int blockSize = 0;
m_pTcpSocket->waitForReadyRead(1);
pData.append( m_pTcpSocket->readAll() );
while(pData.size() != 0)
{
if(pData.size() < sizeof(head_pack))
return ;
//m_iPingCounting = 0;
head_pack headPack;
memcpy((void*)(&headPack), (void *)(&pData.data()[0]), sizeof(head_pack));
if ( headPack.sizePack != headPack.sizePack2 )
{
pData = pData.mid( 1 );
continue;
}
switch(headPack.typePack)
{
// èíôîŵìàöèÿ î ôàéëå
case TYPE_INFO_FILE:
if(headPack.sizePack + sizeof(head_pack) <= pData.size())
{//ŵàçìåŵ ïàêåòà + çàãîëîâîê
pData = pData.mid(sizeof(head_pack));
if( sizeof(sfiledata) <= headPack.sizePack ){
memcpy((char *)&sfiledata,&pData.data()[0],headPack.sizePack);
pData = pData.mid(headPack.sizePack);
}
else{
}
}
else{
return;
}
break;
case TYPE_DATA_FILE:
if(headPack.sizePack + sizeof(head_pack) <= pData.size())
{
pData = pData.mid(sizeof(head_pack));
QFile file;
file.write(&pData.data()[0],headPack.sizePack);
blockSize += headPack.sizePack;
pData = pData.mid(headPack.sizePack);
//std::cout<<"blockSize = "<<blockSize;
if(sfiledata.nFileSize <= blockSize)
{
head_pack headpck;
headpck.sizePack = 1;
headpck.typePack = TYPE_COMMAND;
headpck.sizePack2 = 1;
QByteArray ba_success;
ba_success.append((char*)&headpck,sizeof(head_pack));
ba_success.append(CMD_SUCCESS_RECEIVE_FILE);
m_pTcpSocket->write(ba_success);
m_pTcpSocket->waitForBytesWritten(1);
}
}
else{
return;
}
break;
case TYPE_COMMAND:
if(headPack.sizePack + sizeof(head_pack) <= pData.size()){
pData = pData.mid(sizeof(head_pack));
if(pData.data()[0] == CMD_SUCCESS_RECEIVE_FILE){
setStatusTransmite(SUCCESS);
}
}
else{
return;
}
break;
case TYPE_INFO_PROCESS: //Разбираем посылку с количеством принятых байт сервером на данный момент
if(headPack.sizePack + sizeof(head_pack) <= pData.size()){
pData = pData.mid(sizeof(head_pack));
if( sizeof(int) <= headPack.sizePack ){
int progress;
memcpy((void *)(&progress),(void *)(&pData.data()[0]),sizeof(int));
setProgress(progress);
}
}
else{
return;
}
break;
default:
pData = pData.mid( 1 );
continue;
};
}
return ;
}
void ThreadClient::TransmiteFile()
{
QFile file;
file.setFileName(m_sFilePath);
QFileInfo fi(m_sFilePath);
{
sfiledata.nFileSize = fi.size();
//for(int i = 0; i < max_char; i++)
// sfileData.pFileName[i] = filePath.toAscii().data()[i];
QByteArray ba;
head_pack headPack;
headPack.sizePack = sizeof(sFileData);
qDebug()<<"headPack.sizePack = "<<headPack.sizePack;
headPack.typePack = TYPE_INFO_FILE;
headPack.sizePack2 = sizeof(sFileData);
qDebug()<<"headPack.sizePack2 = "<<headPack.sizePack2;
ba.append((char *)(&headPack),sizeof(head_pack));
ba.append((char*)(&sfiledata),sizeof(sFileData));
m_pTcpSocket->write(ba);
m_pTcpSocket->waitForBytesWritten(1);
setStatusTransmite(IN_PROCESS);
}
{
if(file.open(QFile::ReadWrite)){
file.seek(0);
while(!file.atEnd())
{
const QByteArray buf = file.read(MAX_SIZE_FRAME); //1024
head_pack headPack;
headPack.sizePack = buf.size();
headPack.typePack = TYPE_DATA_FILE;
headPack.sizePack2 = buf.size();
QByteArray ba;
ba.append((char *)(&headPack),sizeof(headPack));
ba.append(buf);
m_pTcpSocket->write(ba);
m_pTcpSocket->waitForBytesWritten(1);
ParsDataRes();
}
}
}
m_bSendFile = false;
}
жуткая мешанина сишного кода, брр
и зачем вообще это всё ?
ведь в начале файла можно передать размер, а на приеме и так ясно сколько принято
ну чтобы была обратная связь, и отображать на стороне клиента в прогресс баре процесс передачи.
Не получается примерно вот что
static int blocksize;
blocksize++;
socket->write((char*)&blocksize,sizeof(int));
переписывай на события readyread чтобы никаких waitForReadyRead и waitForBytesWritten небыло
для прогресса можно обойтись штатными средствами: отправляющий смотрит QTcpSocket::bytesWritten а приемник и так знает сколько принял в событиях QTcpSocket::readyRead
для отмены закрой сокет