fix PIFileTransfer
git-svn-id: svn://db.shs.com.ru/pip@73 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
project(pip)
|
||||
cmake_minimum_required(VERSION 2.6)
|
||||
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
|
||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g3")
|
||||
|
||||
include_directories(${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR})
|
||||
include(CheckFunctionExists)
|
||||
|
||||
@@ -36,6 +36,7 @@ void PIBaseTransfer::stopSend() {
|
||||
void PIBaseTransfer::stopReceive() {
|
||||
if (!is_receiving) return;
|
||||
break_ = true;
|
||||
// piCoutObj << "stopReceive()";
|
||||
finish_receive(false);
|
||||
}
|
||||
|
||||
@@ -46,10 +47,13 @@ void PIBaseTransfer::received(PIByteArray data) {
|
||||
diag.received(data.size(), false);
|
||||
return;
|
||||
}
|
||||
diag.received(data.size(), true);
|
||||
PacketHeader h;
|
||||
data >> h;
|
||||
PacketType pt = (PacketType)h.type;
|
||||
if (!h.check_sig()) {
|
||||
diag.received(data.size(), false);
|
||||
return;
|
||||
} else diag.received(data.size(), true);
|
||||
// piCoutObj << "receive" << h.session_id << h.type << h.id;
|
||||
switch (pt) {
|
||||
case pt_Unknown: break;
|
||||
@@ -84,6 +88,7 @@ void PIBaseTransfer::received(PIByteArray data) {
|
||||
}
|
||||
if (is_receiving && h.id == 0) {
|
||||
if (checkSession() == 0 && pt == pt_ReplySuccess) finish_receive(true);
|
||||
// if (checkSession() == 0 && pt == pt_ReplySuccess) { piCoutObj << "Success receive"; finish_receive(true);}
|
||||
}
|
||||
break;
|
||||
case pt_Break:
|
||||
@@ -103,10 +108,13 @@ void PIBaseTransfer::received(PIByteArray data) {
|
||||
sendBreak(h.session_id);
|
||||
return;
|
||||
}
|
||||
if (header.session_id != h.session_id && is_receiving) {
|
||||
// sendBreak(h.session_id);
|
||||
// return;
|
||||
if (is_receiving) {
|
||||
if (header.session_id != h.session_id) {
|
||||
// sendBreak(h.session_id);
|
||||
// return;
|
||||
// piCoutObj << "restart receive";
|
||||
finish_receive(false, true);
|
||||
} else return;
|
||||
}
|
||||
if (data.size() == sizeof(StartRequest)) {
|
||||
StartRequest sr;
|
||||
@@ -121,10 +129,11 @@ void PIBaseTransfer::received(PIByteArray data) {
|
||||
session.resize(sr.packets);
|
||||
replies.resize(sr.packets + 1);
|
||||
replies.fill(pt_Unknown);
|
||||
is_receiving = true;
|
||||
break_ = false;
|
||||
diag.reset();
|
||||
diag.start(100);
|
||||
// piCoutObj << "receiveStarted()";
|
||||
is_receiving = true;
|
||||
break_ = false;
|
||||
receiveStarted();
|
||||
replies_cnt = send_queue = 0;
|
||||
state_string = "receiving";
|
||||
@@ -140,10 +149,10 @@ void PIBaseTransfer::received(PIByteArray data) {
|
||||
bool PIBaseTransfer::send_process() {
|
||||
packet_header_size = sizeof(PacketHeader) + customHeader().size();
|
||||
break_ = false;
|
||||
is_sending = true;
|
||||
diag.reset();
|
||||
diag.start(100);
|
||||
sendStarted();
|
||||
is_sending = true;
|
||||
replies.resize(session.size() + 1);
|
||||
replies.fill(pt_Unknown);
|
||||
PIByteArray ba;
|
||||
@@ -203,6 +212,7 @@ bool PIBaseTransfer::send_process() {
|
||||
|
||||
|
||||
int PIBaseTransfer::checkSession() {
|
||||
if (!(is_receiving || is_sending)) return -1;
|
||||
int miss = 0;
|
||||
for (int i = 1; i < replies.size_s(); i++) {
|
||||
if (replies[i] != pt_ReplySuccess) miss++;
|
||||
@@ -379,35 +389,38 @@ PIByteArray PIBaseTransfer::build_packet(int id) {
|
||||
|
||||
|
||||
bool PIBaseTransfer::finish_send(bool ok) {
|
||||
is_sending = false;
|
||||
if (ok) state_string = "send done";
|
||||
else state_string = "send failed";
|
||||
// piCoutObj << state_string << PIString::readableSize(bytes_all);
|
||||
is_sending = false;
|
||||
header.id = 0;
|
||||
if (!ok) sendBreak(header.session_id);
|
||||
else sendReply(pt_ReplySuccess);
|
||||
diag.stop();
|
||||
sendFinished(ok);
|
||||
diag.stop();
|
||||
bytes_all = bytes_cur = 0;
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
void PIBaseTransfer::finish_receive(bool ok, bool quet) {
|
||||
is_receiving = false;
|
||||
if (ok) state_string = "receive done";
|
||||
else state_string = "receive failed";
|
||||
// piCoutObj << state_string << PIString::readableSize(bytes_all);
|
||||
is_receiving = false;
|
||||
// piCoutObj << state_string;// << PIString::readableSize(bytes_all);
|
||||
if (!ok && !quet) sendBreak(header.session_id);
|
||||
diag.stop();
|
||||
receiveFinished(ok);
|
||||
diag.stop();
|
||||
bytes_all = bytes_cur = 0;
|
||||
}
|
||||
|
||||
|
||||
void PIBaseTransfer::diagChanged(PIDiagnostics::Quality new_quality, PIDiagnostics::Quality old_quality) {
|
||||
if (is_receiving) {
|
||||
if (new_quality == PIDiagnostics::Failure) stopReceive();
|
||||
if (new_quality == PIDiagnostics::Failure) {
|
||||
piCout << "disconnected!";
|
||||
stopReceive();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -64,13 +64,13 @@ bool PIFileTransfer::send(PIVector<PIFile::FileInfo> entries) {
|
||||
bool PIFileTransfer::sendFiles(const PIVector<PFTFileInfo> &files) {
|
||||
files_ = files;
|
||||
PIStringList names;
|
||||
// piCoutObj << "prepare to send" << files_.size() << "files";
|
||||
// piCoutObj << "prepare to send" << files_.size() << "files";
|
||||
for(int i=0; i<files_.size_s(); i++) {
|
||||
// files_[i].path = dir.relative(files_[i].path);
|
||||
// files_[i].path = dir.relative(files_[i].path);
|
||||
if (names.contains(files_[i].path)) {files_.remove(i); i--;}
|
||||
else names << files_[i].path;
|
||||
if (files_[i].isDir()) files_[i].size = 0;
|
||||
// piCout << "prepare" << i << files_[i].path << files_[i].dest_path << files_[i].name();
|
||||
// piCout << "prepare" << i << files_[i].path << files_[i].dest_path << files_[i].name();
|
||||
}
|
||||
srand(PISystemTime::current().toMilliseconds());
|
||||
pftheader.session_id = rand();
|
||||
@@ -82,25 +82,25 @@ bool PIFileTransfer::sendFiles(const PIVector<PFTFileInfo> &files) {
|
||||
if (!send_process()) return false;
|
||||
pftheader.step = pft_Data;
|
||||
PIVector<Part> pts;
|
||||
for (int i=0; i<files_.size_s(); i++)
|
||||
for (int i=0; i<files_.size_s(); i++) {
|
||||
pts << Part(i+1, files_[i].size);
|
||||
}
|
||||
buildSession(pts);
|
||||
bool ok = send_process();
|
||||
return ok;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void PIFileTransfer::processFile(int id, ullong start, PIByteArray & data) {
|
||||
piCout << "processFile" << id << files_.size();
|
||||
// piCout << "processFile" << id << files_.size();
|
||||
PFTFileInfo fi = files_[id-1];
|
||||
bytes_file_all = fi.size;
|
||||
bytes_file_cur = start;
|
||||
cur_file_string = fi.dest_path;
|
||||
PIString path = dir.absolutePath() + dir.separator + fi.dest_path;
|
||||
piCout << "receive" << path << fi.size << data.size();
|
||||
// piCout << "receive" << path << fi.size << data.size();
|
||||
if (fi.isDir()) {
|
||||
// piCoutObj << "make dir" << fi.entry.path;
|
||||
// piCoutObj << "make dir" << fi.entry.path;
|
||||
if (!PIDir::make(path)) {
|
||||
cur_file_string = "ERROR! while create directory " + path;
|
||||
piCoutObj << cur_file_string;
|
||||
@@ -113,22 +113,22 @@ void PIFileTransfer::processFile(int id, ullong start, PIByteArray & data) {
|
||||
work_file.close();
|
||||
if (!work_file.open(path, PIIODevice::ReadWrite)) {
|
||||
cur_file_string = "ERROR! while open file " + path;
|
||||
piCoutObj << cur_file_string << "," << errorString();
|
||||
piCoutObj << cur_file_string;
|
||||
stopReceive();
|
||||
return;
|
||||
}
|
||||
if (work_file.size() > fi.size) {
|
||||
// piCoutObj << "error size" << work_file.size() << fi.size;
|
||||
// piCoutObj << "error size" << work_file.size() << fi.size;
|
||||
work_file.clear();
|
||||
work_file.resize(fi.size);
|
||||
// piCoutObj << "correct size" << work_file.size() << fi.size;
|
||||
// piCoutObj << "correct size" << work_file.size() << fi.size;
|
||||
}
|
||||
}
|
||||
// piCoutObj << "write file" << path << work_file.path() << work_file.size() << fi.entry.size << work_file.pos() << fi.fstart << fi.fsize;
|
||||
// piCoutObj << "write file" << path << work_file.path() << work_file.size() << fi.entry.size << work_file.pos() << fi.fstart << fi.fsize;
|
||||
if (work_file.size() < (llong)start) {
|
||||
// piCoutObj << "error pos size" << work_file.pos() << fi.fstart;
|
||||
// piCoutObj << "error pos size" << work_file.pos() << fi.fstart;
|
||||
work_file.resize(start);
|
||||
// piCoutObj << "correct pos size" << work_file.pos() << fi.fstart;
|
||||
// piCoutObj << "correct pos size" << work_file.pos() << fi.fstart;
|
||||
}
|
||||
if (work_file.size() > fi.size) {
|
||||
piCoutObj << "****** error size" << work_file.size() << fi.size;
|
||||
@@ -136,7 +136,7 @@ void PIFileTransfer::processFile(int id, ullong start, PIByteArray & data) {
|
||||
work_file.resize(fi.size);
|
||||
piCoutObj << "****** correct size" << work_file.size() << fi.size;
|
||||
}
|
||||
// if (fi.fstart != work_file.pos()) piCoutObj << "error pos" << work_file.pos() << fi.fstart;
|
||||
// if (fi.fstart != work_file.pos()) piCoutObj << "error pos" << work_file.pos() << fi.fstart;
|
||||
work_file.seek(start);
|
||||
int rs = work_file.write(data.data(), data.size());
|
||||
if (rs != data.size_s()) {
|
||||
@@ -150,8 +150,8 @@ void PIFileTransfer::processFile(int id, ullong start, PIByteArray & data) {
|
||||
|
||||
|
||||
PIByteArray PIFileTransfer::buildPacket(Part p) {
|
||||
// piCoutObj << "Step" << pftheader.step;
|
||||
// piCoutObj << "session id" << pftheader.session_id;
|
||||
// piCoutObj << "Step" << pftheader.step;
|
||||
// piCoutObj << "session id" << pftheader.session_id;
|
||||
PIByteArray ba;
|
||||
switch(pftheader.step) {
|
||||
case pft_None:
|
||||
@@ -162,16 +162,16 @@ PIByteArray PIFileTransfer::buildPacket(Part p) {
|
||||
memcpy(ba.data(), desc.data(p.start), p.size);
|
||||
return ba;
|
||||
case pft_Data:
|
||||
// piCout << "send data" << p.id << files_.size();
|
||||
// piCout << "send data" << p.id << files_.size();
|
||||
PIFile::FileInfo fi = files_[p.id-1];
|
||||
if (fi.isFile()) {
|
||||
// piCout << "send file" << fi.name() << fi.size;
|
||||
// piCout << "send file" << fi.name() << fi.size;
|
||||
PIString path = fi.path;
|
||||
if (work_file.path() != path || !work_file.isOpened()) {
|
||||
if (!work_file.open(path, PIIODevice::ReadOnly)) {
|
||||
break_ = true;
|
||||
cur_file_string = "ERROR! while open file " + fi.path;
|
||||
piCoutObj << cur_file_string << "," << errorString();
|
||||
piCoutObj << cur_file_string;
|
||||
stopSend();
|
||||
return PIByteArray();
|
||||
}
|
||||
@@ -179,7 +179,6 @@ PIByteArray PIFileTransfer::buildPacket(Part p) {
|
||||
work_file.seek(p.start);
|
||||
ba.resize(p.size);
|
||||
int rs = work_file.read(ba.data(), ba.size());
|
||||
piCout << rs << p.size;
|
||||
if ((llong)rs != (llong)p.size) {
|
||||
break_ = true;
|
||||
cur_file_string = "ERROR! while read file " + fi.path + " (must " + PIString::fromNumber(p.size) + ", but read " + PIString::fromNumber(rs) + ")";
|
||||
@@ -188,10 +187,10 @@ PIByteArray PIFileTransfer::buildPacket(Part p) {
|
||||
return PIByteArray();
|
||||
}
|
||||
}
|
||||
// if (fi.isDir()) {
|
||||
// piCout << "create dir" << fi.path;
|
||||
// dir.make(fi.path);
|
||||
// }
|
||||
// if (fi.isDir()) {
|
||||
// piCout << "create dir" << fi.path;
|
||||
// dir.make(fi.path);
|
||||
// }
|
||||
cur_file_string = fi.path;
|
||||
bytes_file_all = fi.size;
|
||||
bytes_file_cur = p.start;
|
||||
@@ -203,9 +202,9 @@ PIByteArray PIFileTransfer::buildPacket(Part p) {
|
||||
|
||||
void PIFileTransfer::receivePart(PIBaseTransfer::Part fi, PIByteArray ba, PIByteArray pheader) {
|
||||
PFTHeader h;
|
||||
// piCout << pheader.size() << sizeof(PFTHeader);
|
||||
// piCout << pheader.size() << sizeof(PFTHeader);
|
||||
pheader >> h;
|
||||
// piCout << h.session_id;
|
||||
// piCout << h.session_id;
|
||||
StepType st = (StepType)h.step;
|
||||
pftheader.step = st;
|
||||
if (!h.check_sig()) {
|
||||
@@ -243,6 +242,7 @@ PIByteArray PIFileTransfer::customHeader() {
|
||||
void PIFileTransfer::receive_started() {
|
||||
if (pftheader.step == pft_None) {
|
||||
files_.clear();
|
||||
// piCoutObj << "start receive";
|
||||
receiveFilesStarted();
|
||||
}
|
||||
}
|
||||
@@ -252,10 +252,11 @@ void PIFileTransfer::receive_finished(bool ok) {
|
||||
if (pftheader.step == pft_Description) {
|
||||
bool user_ok = true;
|
||||
if (ok) {
|
||||
// piCoutObj << desc.size() << PICoutManipulators::Hex << desc;
|
||||
desc >> files_;
|
||||
// piCoutObj << files_;
|
||||
PIStringList files;
|
||||
piForeachC(PFTFileInfo &fi, files_) files << fi.dest_path;
|
||||
//piCout << files;
|
||||
receiveFilesRequest(files, bytesAll(), &user_ok);
|
||||
}
|
||||
if (!ok || !user_ok) {
|
||||
|
||||
@@ -75,7 +75,7 @@ private:
|
||||
virtual void receivePart(Part fi, PIByteArray ba, PIByteArray pheader);
|
||||
virtual PIByteArray buildPacket(Part fi);
|
||||
virtual PIByteArray customHeader();
|
||||
//EVENT_HANDLER(void, send_started);
|
||||
// EVENT_HANDLER(void, send_started);
|
||||
EVENT_HANDLER(void, receive_started);
|
||||
EVENT_HANDLER1(void, send_finished, bool, ok);
|
||||
EVENT_HANDLER1(void, receive_finished, bool, ok);
|
||||
@@ -89,4 +89,13 @@ inline PIByteArray & operator <<(PIByteArray & s, const PIFileTransfer::PFTFileI
|
||||
inline PIByteArray & operator >>(PIByteArray & s, PIFileTransfer::PFTFileInfo & v) {s >> v.dest_path >> v.size >> v.time_access >> v.time_modification >>
|
||||
*(int*)(&(v.flags)) >> v.id_user >> v.id_group >> v.perm_user.raw >> v.perm_group.raw >> v.perm_other.raw; return s;}
|
||||
|
||||
inline PICout operator <<(PICout s, const PIFileTransfer::PFTFileInfo & v) {
|
||||
s.setControl(0, true);
|
||||
s << "FileInfo(\"" << v.dest_path << "\", " << PIString::readableSize(v.size) << ", "
|
||||
<< v.perm_user.toString() << " " << v.perm_group.toString() << " " << v.perm_other.toString() << ", "
|
||||
<< v.time_access.toString() << ", " << v.time_modification.toString()
|
||||
<< ", 0x" << PICoutManipulators::Hex << v.flags << ")";
|
||||
s.restoreControl();
|
||||
return s;
|
||||
}
|
||||
#endif // PIFILETRANSFER_H
|
||||
|
||||
@@ -50,7 +50,12 @@ private:
|
||||
|
||||
EVENT_HANDLER(void, ftevent) {
|
||||
if (quet_) return;
|
||||
PICout(AddSpaces) << ClearLine << ft.stateString()
|
||||
#ifdef WINDOWS
|
||||
piCout
|
||||
#else
|
||||
PICout(AddSpaces) << ClearLine
|
||||
#endif
|
||||
<< ft.stateString() << ft.curFile()
|
||||
<< PIString::readableSize(ft.diagnostic().receiveBytesPerSec()) + "/s"
|
||||
<< PIString::readableSize(ft.diagnostic().sendBytesPerSec()) + "/s"
|
||||
<< "(" << PIString::readableSize(ft.bytesFileCur()) << "/" << PIString::readableSize(ft.bytesFileAll()) << ", "
|
||||
@@ -59,7 +64,10 @@ private:
|
||||
PIString::fromNumber(PISystemTime::fromSeconds((ft.bytesAll() - ft.bytesCur()) /
|
||||
ft.diagnostic().receiveBytesPerSec()).toSeconds())
|
||||
: PIString("unknown"))
|
||||
<< Flush;
|
||||
#ifndef WINDOWS
|
||||
<< Flush
|
||||
#endif
|
||||
;
|
||||
}
|
||||
|
||||
EVENT_HANDLER1(void, ftsend, PIByteArray &, data) {
|
||||
|
||||
Reference in New Issue
Block a user