Создание клиент-серверного приложения

Разработка системы, базирующейся на протоколе LIMone, для обмена мгновенными сообщениями и пересылки файлов в процессе деловой переписки. Реализация системы в виде клиент-серверного приложения. Расчет экономических показателей программного продукта.

Рубрика Программирование, компьютеры и кибернетика
Вид дипломная работа
Язык русский
Дата добавления 22.08.2016
Размер файла 4,7 M

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

return;

}

if (!inpack.decode_header(h))

{

disconnect_form_server();

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Заголовок испорчен. "

"Соединение сброшено!"));

return;

}

if (h.packtype != HEADER_PACKAGE_TYPE::GENERAL::ROOT_AUTHORIZATION)

return;

if (!inpack.decode_TLV(TLVS::OK, tlv))

{

disconnect_form_server();

if (inpack.decode_TLV(TLVS::ERRORS, tlv))

QMessageBox::critical(this, trUtf8("Авторизация администратора"),

QString::fromStdString(tlv.getString()));

else

QMessageBox::critical(this, trUtf8("Авторизация администратора"),

trUtf8("Не обнаружены поля OK|ERR"));

return;

}

conn_wgt->pb_inc();

outpack.clear();

outpack.generate_header(HEADER_PACKAGE_TYPE::CONTACT_LIST::GET_GROUP_LIST);

cnt = send_to_server(outpack, "Список групп не может быть запрошен!");

if (cnt < 0) return;

conn_wgt->pb_inc();

outpack.clear();

outpack.generate_header(HEADER_PACKAGE_TYPE::CONTACT_LIST::GET_CONTACT_LIST);

cnt = send_to_server(outpack, "Список собеседников не может быть запрошен!");

if (cnt < 0) return;

conn_wgt->pb_inc();

outpack.clear();

conn_wgt->show_buttons();

conn_wgt->close();

show();

slot_read();

connect(sock, SIGNAL(readyRead()), SLOT(slot_read()));

keep_alive->start();

}

void Widget::slot_read()

{

if (!sock->isOpen()) return;

int bytes_read;

while (sock->bytesAvailable() > 0)

{

bytes_read = read_from_server(inpack);

if (bytes_read < 0)

{

disconnect_form_server();

return;

}

if (bytes_read < HEADER_OFFSET) return;

parsePack(inpack);

}

}

void Widget::parsePack(Package &inpack)

{

HEADER h;

if (!inpack.decode_header(h)) return;

switch (h.packtype)

{

case HEADER_PACKAGE_TYPE::CONTACT_LIST::GET_GROUP_LIST:

{

TLV tlv;

if (inpack.decode_TLV(TLVS::OK, tlv))

{

loaded_groups++;

if (loaded_groups == 2) emit readyContactList();

return;

}

Group p;

if (!inpack.read_group_info(p)) return;

foreach (Group grp, GroupList)

if (grp.GroupID == p.GroupID) return;

GroupList.append(p);

return;

}

case HEADER_PACKAGE_TYPE::CONTACT_LIST::GET_CONTACT_LIST:

{

TLV tlv;

if (inpack.decode_TLV(TLVS::OK, tlv))

{

loaded_groups++;

if (loaded_groups == 2) emit readyContactList();

return;

}

Contact p;

if (!inpack.read_user_info_with_status(p)) return;

foreach (Contact cont, ContactList)

if (cont.UIN == p.UIN) return;

ContactList.append(p);

return;

}

case HEADER_PACKAGE_TYPE::AUTHORIZATION::CHANGE_USER_STATUS:

{

string uin;

STATUS status;

string status_text;

TLV tlv;

if (inpack.decode_TLV(TLVS::UIN, tlv)) uin = tlv.getString();

else return;

if (inpack.decode_TLV(TLVS::STATUS, tlv))

status = tlv.getUIntN<STATUS>();

else return;

if (inpack.decode_TLV(TLVS::STATUS_TEXT, tlv))

status_text = tlv.getString();

else status_text = string();

for (int i = 0; i < ContactList.size(); i++)

if (ContactList.value(i).UIN == uin)

{

ContactList[i].Status = status;

ContactList[i].StatusText = status_text;

if (ContactList.value(i).reference != NULL)

{

QTreeWidgetItem* contact_item =

(QTreeWidgetItem*)ContactList.value(i).reference;

contacts_tree->setContactStatus(contact_item, status,

status_text);

}

else emit readyContactList();

return;

}

return;

}

case HEADER_PACKAGE_TYPE::AUTHORIZATION::CHANGE_USER_INFO:

{

Contact p;

if (!inpack.read_base_user_info(p)) return;

contacts_tree->correctionContact(p);

return;

}

case HEADER_PACKAGE_TYPE::CONTACT_LIST::CREATE_USER:

{

Contact p;

if (!inpack.read_base_user_info(p)) return;

p.reference = NULL;

ContactList.append(p);

contacts_tree->correctionContact(p);

return;

}

case HEADER_PACKAGE_TYPE::CONTACT_LIST::CREATE_GROUP:

{

Group p;

if (!inpack.read_group_info(p)) return;

QTreeWidgetItem* new_item = NULL;

if (p.ParentGroupID == 0)

new_item =

new QTreeWidgetItem(contacts_tree->invisibleRootItem());

else

{

for (int i = 0; i < GroupList.size(); i++)

if (GroupList.value(i).GroupID == p.ParentGroupID)

{

if (GroupList.value(i).reference == NULL) return;

new_item =

(QTreeWidgetItem*) GroupList.value(i).reference;

new_item = new QTreeWidgetItem(new_item);

break;

}

if (new_item == NULL) return;

}

p.reference = new_item;

GroupList.append(p);

new_item->setText(0, QString::fromStdString(p.Name));

new_item->setIcon(0, QPixmap(":/images/group.png"));

return;

}

}

}

bool Widget::getNeededPack(PACKTYPE packtype, Package &pack)

{

int bytes_read = 0;

HEADER h;

while (sock->bytesAvailable() > 0 || sock->waitForReadyRead())

{

bytes_read = read_from_server(pack);

if (bytes_read < HEADER_OFFSET) continue;

if (!pack.decode_header(h)) return false;

if (h.seq != 0 && h.packtype == packtype) return true;

else parsePack(pack);

}

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Сервер не отвечает!"));

return false;

}

void Widget::slot_change_root_password(QString oldp, QString newp)

{

disconnect(sock, SIGNAL(readyRead()), this, SLOT(slot_read()));

keep_alive->stop();

TLV tlv;

outpack.clear();

string cipher;

string oldpass = oldp.toStdString();

RSAES_OAEP_SHA_Encryptor e(*serverPublicKey);

StringSource(oldpass, true, new PK_EncryptorFilter(rng, e,

new StringSink(cipher)));

outpack.write_TLV(TLVS::PASSWORD, cipher);

string newpass = newp.toStdString();

cipher.clear();

StringSource(newpass, true, new PK_EncryptorFilter(rng, e,

new StringSink(cipher)));

outpack.write_TLV(TLVS::NEW_PASSWORD, cipher);

outpack.generate_header(HEADER_PACKAGE_TYPE::GENERAL::CHANGE_ROOT_PASSWORD);

int cnt = send_to_server(outpack, "Невозможно "

"отправить запрос на смену пароля!");

if (cnt < 0) return;

outpack.clear();

if (getNeededPack(HEADER_PACKAGE_TYPE::GENERAL::CHANGE_ROOT_PASSWORD,

outpack))

{

if (outpack.decode_TLV(TLVS::OK, tlv))

{

QMessageBox::information(this,

trUtf8("Смена пароля администратора"),

trUtf8("Пароль заменен :)"));

chrtpass_wgt->close();

}

else

{

if (outpack.decode_TLV(TLVS::ERRORS, tlv))

QMessageBox::critical(this,

trUtf8("Смена пароля администратора"),

QString::fromStdString(tlv.getString()));

else QMessageBox::critical(this,

trUtf8("Смена пароля администратора"),

trUtf8("Не обнаружены поля OK|ERR"));

}

}

else return;

slot_read();

connect(sock, SIGNAL(readyRead()), SLOT(slot_read()));

keep_alive->start();

}

void Widget::slot_new_uin(Contact p)

{

disconnect(sock, SIGNAL(readyRead()), this, SLOT(slot_read()));

keep_alive->stop();

TLV tlv;

outpack.clear();

outpack.write_base_user_info(p);

string cipher;

RSAES_OAEP_SHA_Encryptor e(*serverPublicKey);

StringSource(p.Password, true,

new PK_EncryptorFilter(rng, e,

new StringSink(cipher)

) // PK_EncryptorFilter

); // StringSource

outpack.write_TLV(TLVS::PASSWORD, cipher);

outpack.generate_header(HEADER_PACKAGE_TYPE::CONTACT_LIST::CREATE_USER);

int cnt = send_to_server(outpack, "Невозможно "

"отправить запрос на создание UIN!");

if (cnt < 0) return;

outpack.clear();

if (getNeededPack(HEADER_PACKAGE_TYPE::CONTACT_LIST::CREATE_USER,

outpack))

{

if (outpack.decode_TLV(TLVS::OK, tlv))

newuin_wgt->close();

else

{

if (outpack.decode_TLV(TLVS::ERRORS, tlv))

QMessageBox::critical(this,

trUtf8("Создание нового пользователя"),

QString::fromStdString(tlv.getString()));

else QMessageBox::critical(this,

trUtf8("Создание нового пользователя"),

trUtf8("Не обнаружены поля OK|ERR"));

}

}

else return;

slot_read();

connect(sock, SIGNAL(readyRead()), SLOT(slot_read()));

keep_alive->start();

}

Приложение Г Исходный код клиента

Модуль widget: widget.cpp

void Widget::slot_send_message(QString UIN, GROUP_ID gid, QString mess)

{

disconnect(sock, SIGNAL(readyRead()), this, SLOT(slot_read()));

keep_alive->stop();

TLV tlv;

outpack.clear();

if (!UIN.isEmpty())

outpack.write_TLV(TLVS::UIN, UIN.toStdString());

else outpack.write_TLV(TLVS::GROUP_ID, gid);

// шифрование сообщения

byte iv[AES::BLOCKSIZE];

memset(iv, 0x00, AES::BLOCKSIZE);

string plaintext = mess.toStdString();

string ciphertext;

AES::Encryption aesEncryption(message_key, MESSAGE_KEY_SIZE);

CBC_Mode_ExternalCipher::Encryption cbcEncryption(aesEncryption, iv);

StringSource(plaintext, true,

new StreamTransformationFilter(cbcEncryption,

new StringSink(ciphertext)));

// шифр получен

outpack.write_TLV(TLVS::MESSAGE, ciphertext);

outpack.generate_header(HEADER_PACKAGE_TYPE::MESSAGES::SEND_MESSAGE);

int cnt = send_to_server(outpack, "Невозможно отправить сообщение!");

if (cnt < 0) return;

outpack.clear();

if (getNeededPack(HEADER_PACKAGE_TYPE::MESSAGES::SEND_MESSAGE, outpack))

{

if (!outpack.decode_TLV(TLVS::OK, tlv))

{

if (outpack.decode_TLV(TLVS::ERRORS, tlv))

conv_wgt->showError(UIN,

QString::fromStdString(tlv.getString()));

else

conv_wgt->showError(UIN, trUtf8("Не обнаружены поля OK|ERR"));

}

}

else return;

slot_read();

connect(sock, SIGNAL(readyRead()), SLOT(slot_read()));

keep_alive->start();

}

int FilesTransferWidget::send_to_server(Package &pack)

{

if (!sock->isOpen()) return -1;

int cnt;

if ((cnt = sock->write(pack.buffer(), pack.getPackLength())) !=

pack.getPackLength())

return -1;

return cnt;

}

void FilesTransferWidget::addFileToTransfer(QString UIN, QString FileName)

{

File2 new_fl;

new_fl.UIN_to = UIN.toStdString();

new_fl.FileName = FileName.toStdString();

new_fl.FileSize = QFile(FileName).size();

new_fl.current_part = 0;

new_fl.fd = new QFile(FileName);

if (!new_fl.fd->open(QIODevice::ReadOnly))

{

QMessageBox::critical(this, trUtf8("Ошибка"),

trUtf8("Файл не может быть открыт!"));

delete new_fl.fd;

return;

}

QTreeWidgetItem* new_item = new QTreeWidgetItem(this);

new_fl.reference = new_item;

new_item->setText(0, QFileInfo(FileName).fileName());

new_item->setIcon(0, QIcon(QPixmap(":/file-transfer/file-transfer-"

"upload.png")));

for (int i = 0; i < ContactList.size(); i++)

if (ContactList[i].UIN == new_fl.UIN_to)

{

new_item->setText(1,

QString::fromStdString(ContactList[i].Surname) +

trUtf8(" ") +

QString::fromStdString(

ContactList[i].Name).at(0) +

trUtf8(" ") +

QString::fromStdString(

ContactList[i].Patronymic).at(0));

break;

}

QToolButton *cancel_btn = new QToolButton(this);

cancel_btn->setIcon(QIcon(QPixmap(":/file-transfer/file-transfer"

"-stop.png")));

cancel_btn->setToolButtonStyle(Qt::ToolButtonIconOnly);

cancel_btn->setToolTip(trUtf8("Отменить передачу файла"));

cancel_btn->setAutoRaise(true);

connect(cancel_btn, SIGNAL(clicked()), SLOT(sendCancelFile()));

setItemWidget(new_item, 2, cancel_btn);

QProgressBar *pgb = new QProgressBar(this);

pgb->setRange(0, new_fl.FileSize/MAX_FILE_PART_SIZE + 1);

pgb->reset();

pgb->setTextVisible(true);

setItemWidget(new_item, 3, pgb);

new_item->setText(4, FileName);

filebuf.clear();

filebuf.write_TLV(TLVS::FILE_NAME, new_item->text(0).toStdString());

filebuf.write_TLV(TLVS::FILE_SIZE, new_fl.FileSize);

filebuf.write_TLV(TLVS::UIN, new_fl.UIN_to);

filebuf.generate_header(HEADER_PACKAGE_TYPE::MESSAGES::SEND_FILE_REQUEST);

new_fl.SeqNumber = filebuf.getPackSeqNumber();

send_to_server(filebuf);

SendingFiles.append(new_fl);

resizeColumnToContents(0);

resizeColumnToContents(1);

resizeColumnToContents(2);

show();

}

void FilesTransferWidget::fileTransferAssignID(Package &pack)

{

// Назначается ID передаваемому файлу.

int i;

HEADER h;

if (!pack.decode_header(h)) return;

// Найдем файл по номеру пакета.

for (i = 0; i < SendingFiles.size(); i++)

if (SendingFiles.value(i).SeqNumber == h.seq)

break;

if (i == SendingFiles.size()) return;

TLV tlv;

if (pack.decode_TLV(TLVS::ERRORS, tlv))

{

emit showTrayMessage(trUtf8("Установка ID файла: ") +

QFileInfo(

QString::fromStdString(

SendingFiles[i].FileName)).fileName(),

QString::fromStdString(tlv.getString()),

QSystemTrayIcon::Critical);

deleteFileRecord(SendingFiles, i, Error,

QString::fromStdString(tlv.getString()), false);

return;

}

if (pack.decode_TLV(TLVS::FILE_ID, tlv))

SendingFiles[i].FileID = tlv.getUIntN<FILE_ID>();

}

void FilesTransferWidget::fileTransferAccepted(Package &pack)

{

// Рассматривается accept на запрос передачи файла.

TLV tlv;

int i;

if (pack.decode_TLV(TLVS::FILE_ID, tlv))

{

FILE_ID fid = tlv.getUIntN<FILE_ID>();

for (i = 0; i < SendingFiles.size(); i++)

if (SendingFiles.value(i).FileID == fid)

break;

if (i == SendingFiles.size())

{

// Отправка файла отменена пользователем, выслать CANCEL.

Package pack2;

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::FILE_CANCEL);

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_SENDER_CHANNEL);

send_to_server(pack2);

return;

}

if (pack.decode_TLV(TLVS::OK, tlv))

{

SendingFiles[i].accepted = true;

SendingFiles[i].finished = false;

SendingFiles[i].canceled = false;

sendNewPartsOfFiles();

}

else

{

if (pack.decode_TLV(TLVS::ERRORS, tlv))

{

emit showTrayMessage(trUtf8("Подтверждение отправка файла: ") +

QFileInfo(QString::fromStdString(

SendingFiles[i].FileName

)

).fileName(),

QString::fromStdString(tlv.getString()),

QSystemTrayIcon::Critical);

deleteFileRecord(SendingFiles, i, Error,

QString::fromStdString(tlv.getString()),

false);

return;

}

else

emit showTrayMessage(trUtf8("Подтверждение отправка файла: ") +

QFileInfo(QString::fromStdString(

SendingFiles[i].FileName

)

).fileName(),

trUtf8("Не обнаружены поля OK|ERR"),

QSystemTrayIcon::Critical);

}

}

else

emit showTrayMessage(trUtf8("Подтверждение отправка файла"),

trUtf8("Не указан ID файла!"),

QSystemTrayIcon::Critical);

}

void FilesTransferWidget::sendNewPartsOfFiles()

{

if (sock->bytesToWrite() > 0) return;

// Отправка порции файла.

if (SendingFiles.isEmpty()) return;

int old_sending_file_number = sending_file_number;

while (!SendingFiles[sending_file_number].accepted ||

SendingFiles[sending_file_number].canceled ||

SendingFiles[sending_file_number].finished)

{

sending_file_number++;

if (sending_file_number >= SendingFiles.size())

sending_file_number = 0;

if (sending_file_number == old_sending_file_number) return;

}

filebuf.clear();

filebuf.write_TLV(TLVS::FILE_ID,

SendingFiles[sending_file_number].FileID);

uint8_t fpart[MAX_FILE_PART_SIZE];

int bytes =

SendingFiles[sending_file_number].fd->read((char*)fpart,

MAX_FILE_PART_SIZE);

if (bytes > 0)

{

filebuf.write_TLV(TLVS::FILE_PART,

SendingFiles[sending_file_number].current_part++);

filebuf.write_TLV(TLVS::FILE_BODY, bytes, fpart);

filebuf.generate_header(HEADER_PACKAGE_TYPE::MESSAGES::SEND_FILE_PART);

if (SendingFiles[sending_file_number].reference != NULL)

{

QTreeWidgetItem* item = (QTreeWidgetItem*)

SendingFiles[sending_file_number].reference;

QProgressBar *pb = (QProgressBar*)itemWidget(item, 3);

pb->setValue(pb->value() + 1);

}

}

else

{

if (bytes < 0)

{

// Файл испорчен или был удален в процессе передачи.

filebuf.write_TLV(TLVS::ERRORS,

string("Исходный файл испорчен или удален!"));

filebuf.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_SENDER_CHANNEL);

send_to_server(filebuf);

deleteFileRecord(SendingFiles, sending_file_number, Error,

trUtf8("Исходный файл испорчен или удален!"),

false);

if (sending_file_number >= SendingFiles.size())

sending_file_number = 0;

return;

}

// Передача файла завершена, выслать хэш.

SendingFiles[sending_file_number].fd->close();

SendingFiles[sending_file_number].finished = true;

CryptoPP::Weak1::MD5 hash;

byte hash_buf[2*CryptoPP::Weak1::MD5::DIGESTSIZE];

string str_fname = SendingFiles[sending_file_number].FileName;

#if defined(_OS_WINDOWS_)

QString fname = QString::fromStdString(

SendingFiles[sending_file_number].FileName);

QTextCodec::setCodecForCStrings(

QTextCodec::codecForName("Windows-1251"));

str_fname = fname.toStdString();

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

#endif

CryptoPP::FileSource f(str_fname.c_str(),

true, new CryptoPP::HashFilter(hash,

new CryptoPP::HexEncoder(

new CryptoPP::ArraySink(hash_buf,

2*CryptoPP::Weak1::MD5::DIGESTSIZE))));

filebuf.write_TLV(TLVS::FILE_HASH, 2*CryptoPP::Weak1::MD5::DIGESTSIZE,

hash_buf);

filebuf.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_SENDER_CHANNEL);

}

send_to_server(filebuf);

// Переходим к следующему отправляемому файлу.

sending_file_number++;

if (sending_file_number >= SendingFiles.size())

sending_file_number = 0;

}

void FilesTransferWidget::newFilePart(Package &pack)

{

// Запись порции загружаемого файла на диск.

TLV tlv;

FILE_ID fid;

int i;

if (pack.decode_TLV(TLVS::FILE_ID, tlv))

fid = tlv.getUIntN<FILE_ID>();

else return;

for (i = 0; i < ReceivingFiles.size(); i++)

if (ReceivingFiles.value(i).FileID == fid)

break;

if (i == ReceivingFiles.size())

{

// Получение файла отменено пользователем, выслать CANCEL.

Package pack2;

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::FILE_CANCEL);

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

return;

}

if (!ReceivingFiles[i].accepted || ReceivingFiles[i].finished ||

ReceivingFiles[i].canceled) return;

FPART_NUMBER new_part;

if (pack.decode_TLV(TLVS::FILE_PART, tlv))

new_part = tlv.getUIntN<FPART_NUMBER>();

else

{

Package pack2;

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::ERRORS,

string("Не указан номер части файла!"));

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles.value(i).FileName)).fileName(),

trUtf8("Ошибка загрузки"),

QSystemTrayIcon::Critical);

deleteFileRecord(ReceivingFiles, i, Error,

trUtf8("Не указан номер части файла!"), true);

return;

}

if (new_part > ReceivingFiles[i].current_part)

{

// Потерялась часть файла.

Package pack2;

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::ERRORS, string("Потеряна часть файла!"));

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles.value(i).FileName)).fileName(),

trUtf8("Ошибка загрузки"),

QSystemTrayIcon::Critical);

deleteFileRecord(ReceivingFiles, i, Error,

trUtf8("Потеряна часть файла!"), true);

return;

}

else if (new_part < ReceivingFiles[i].current_part) return;

ReceivingFiles[i].current_part++;

if (pack.decode_TLV(TLVS::FILE_BODY, tlv))

{

FSIZE len = ReceivingFiles[i].fd->write((char*)tlv.V, tlv.L);

ReceivingFiles[i].received_bytes += len;

if (len != tlv.L)

{

Package pack2;

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::ERRORS,

string("Закончилось место на диске!"));

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles[i].FileName

)

).fileName(),

trUtf8("Закончилось место на диске"),

QSystemTrayIcon::Critical);

deleteFileRecord(ReceivingFiles, i, Error,

trUtf8("Закончилось место на диске!"), true);

return;

}

if (ReceivingFiles[i].reference != NULL)

{

QTreeWidgetItem* item =

(QTreeWidgetItem*) ReceivingFiles[i].reference;

QProgressBar *pb = (QProgressBar*)itemWidget(item, 3);

pb->setValue(pb->value() + 1);

}

}

else

{

Package pack2;

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::ERRORS,

string("Отсутствует тело части файла!"));

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles[i].FileName

)

).fileName(),

trUtf8("Ошибка загрузки"),

QSystemTrayIcon::Critical);

deleteFileRecord(ReceivingFiles, i, Error,

trUtf8("Отсутствует тело части файла!"), true);

return;

}

}

void FilesTransferWidget::sender_channel(Package &pack)

{

// Высылаемые со стороны отправителя, я - получатель.

TLV tlv;

FILE_ID fid;

int i;

if (pack.decode_TLV(TLVS::FILE_ID, tlv))

fid = tlv.getUIntN<FILE_ID>();

else return;

for (i = 0; i < ReceivingFiles.size(); i++)

if (ReceivingFiles.value(i).FileID == fid)

break;

if (i == ReceivingFiles.size())

{

// Получение файла отменено мной, выслать CANCEL.

Package pack2;

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::FILE_CANCEL);

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

return;

}

if (pack.decode_TLV(TLVS::FILE_HASH, tlv))

{

// Пришел хэш файла, значит загрузка завершена, закроем файл

// и посчитаем его хэш чтобы сравнить.

Package pack2;

ReceivingFiles[i].finished = true;

ReceivingFiles[i].fd->flush();

ReceivingFiles[i].fd->close();

if (ReceivingFiles[i].received_bytes != ReceivingFiles[i].FileSize)

{

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::ERRORS,

string("Файл загружен не полностью!"));

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles[i].FileName

)

).fileName(),

trUtf8("Ошибка загрузки"),

QSystemTrayIcon::Critical);

deleteFileRecord(ReceivingFiles, i, Error,

trUtf8("Файл загружен не полностью!"), true);

return;

}

if (tlv.L != 2*CryptoPP::Weak1::MD5::DIGESTSIZE)

{

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::ERRORS, string("MD5 хэш испорчен!"));

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles[i].FileName

)

).fileName(),

trUtf8("Невозможно проверить "

"корректность файла"),

QSystemTrayIcon::Warning);

deleteFileRecord(ReceivingFiles, i, Ready,

trUtf8("Невозможно проверить корректность файла!"),

false);

return;

}

CryptoPP::Weak1::MD5 hash;

byte hash_buf[2*CryptoPP::Weak1::MD5::DIGESTSIZE];

string str_fname = ReceivingFiles.value(i).FileName;

#if defined(_OS_WINDOWS_)

QString fname =

QString::fromStdString(ReceivingFiles.value(i).FileName);

QTextCodec::setCodecForCStrings(

QTextCodec::codecForName("Windows-1251"));

str_fname = fname.toStdString();

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

#endif

CryptoPP::FileSource f(str_fname.c_str(),

true, new CryptoPP::HashFilter(hash,

new CryptoPP::HexEncoder(

new CryptoPP::ArraySink(hash_buf,

2*CryptoPP::Weak1::MD5::DIGESTSIZE))));

for (int k = 0; k < 2*CryptoPP::Weak1::MD5::DIGESTSIZE; k++)

if (tlv.V[k] != hash_buf[k])

{

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::ERRORS,

string("MD5 файла не совпадают!"));

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles[i].FileName

)

).fileName(),

trUtf8("Загруженный файл испорчен"),

QSystemTrayIcon::Critical);

deleteFileRecord(ReceivingFiles, i, Error,

trUtf8("Загруженный файл испорчен!"), true);

return;

}

pack2.write_TLV(TLVS::FILE_ID, fid);

pack2.write_TLV(TLVS::OK);

pack2.generate_header(

HEADER_PACKAGE_TYPE::MESSAGES::FILE_RECEIVER_CHANNEL);

send_to_server(pack2);

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles[i].FileName

)

).fileName(),

trUtf8("Файл загружен :)"),

QSystemTrayIcon::Information);

if (ReceivingFiles.value(i).reference != NULL)

{

QTreeWidgetItem* item =

(QTreeWidgetItem*) ReceivingFiles.value(i).reference;

removeItemWidget(item, 3);

QToolButton *open_btn = new QToolButton(this);

open_btn->setIcon(QIcon(QPixmap(":/file-transfer/file-transfer"

"-open.png")));

open_btn->setToolButtonStyle(Qt::ToolButtonIconOnly);

open_btn->setToolTip(trUtf8("Открыть файл"));

open_btn->setAutoRaise(true);

connect(open_btn, SIGNAL(clicked()), SLOT(slotOpenFile()));

setItemWidget(item, 3, open_btn);

QToolButton* cbtn = (QToolButton*)itemWidget(item, 2);

cbtn->setToolTip(trUtf8("Удалить запись"));

cbtn->setIcon(QIcon(QPixmap(":/file-transfer/row-delete.png")));

}

delete ReceivingFiles.value(i).fd;

ReceivingFiles.removeAt(i);

return;

}

if (pack.decode_TLV(TLVS::FILE_CANCEL, tlv))

{

// Отправитель отменил передачу. Удалим запись о файле и сам файл.

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles[i].FileName

)

).fileName(),

trUtf8("Загрузка файла отменена отправителем"),

QSystemTrayIcon::Critical);

deleteFileRecord(ReceivingFiles, i, Cancel,

trUtf8("Загрузка файла отменена отправителем"), true);

return;

}

if (pack.decode_TLV(TLVS::ERRORS, tlv))

{

// На стороне отправителя произошла ошибка.

// Удалим запись о файле и сам файл.

emit showTrayMessage(trUtf8("Загрузка файла: ") +

QFileInfo(QString::fromStdString(

ReceivingFiles[i].FileName

)

).fileName(),

QString::fromStdString(tlv.getString()),

QSystemTrayIcon::Critical);

deleteFileRecord(ReceivingFiles, i, Error,

QString::fromStdString(tlv.getString()), true);

return;

}

}

Размещено на Allbest.ru


Подобные документы

  • Создание клиент-серверного приложения "Чат" с помощью среды визуальной разработки приложений Borland C++ Builder версии 6. Описание функциональности приложения: наличие клиент-серверной архитектуры, обмен короткими сообщениями, а также передача файлов.

    курсовая работа [302,0 K], добавлен 30.01.2012

  • Изучение истории достижений корпорации Oracle. Разработка клиент-серверного приложения на языке Delphi XE, реализующего возможность управления персоналом на предприятии. Основные структуры данных. Создание инструкции работы с приложением "Отдел кадров".

    дипломная работа [974,7 K], добавлен 08.06.2013

  • Сетевое программное обеспечение: общее понятие, содержание, функции. Этапы развития теории компьютерных сетей. Проектирование в среде программирования Borland Builder C++ клиент серверного приложения с использованием сокетов, листинг данной программы.

    курсовая работа [191,5 K], добавлен 07.01.2015

  • Многоуровневые архитектуры клиент–сервер. Диаграммы классов, реализующих уровни презентации, бизнес–логики и базы данных приложения. Словесное описание процесса выполнения транзакций. Создание, изменение и удаление хранимых процедур, их выполнение.

    курсовая работа [3,4 M], добавлен 23.03.2013

  • Разработка компьютерной сети. Спецификация и расчет себестоимости спроектированной сети. Выбор инструментальных средств для реализации разрабатываемого клиент-серверного приложения. Описание логической структуры программного продукта, основные алгоритмы.

    курсовая работа [942,1 K], добавлен 19.03.2012

  • Разработка конфигурации службы. Исследование вычислительной эффективности алгоритма оптимизации. Программная реализация клиент-серверного приложения. Алгоритм решения непрерывной задачи загрузки рюкзака. Подключение веб-сервиса к клиентскому приложению.

    курсовая работа [1,4 M], добавлен 21.01.2017

  • Разработка клиент-серверного приложения, позволяющего взаимодействовать друг с другом с использованием доступа к базам данных. Проектирование связи сервера с базой данных с помощью технологии ODBC. Разработка интерфейса программы, ее тестирование.

    курсовая работа [352,0 K], добавлен 24.08.2016

  • Основные концепции разработки приложения в трёхуровневой архитектуре. Проектное решение, реализующее модель реляционной БД. Спецификация на разработку интерфейса. Описание выполнения транзакций прибытия и убытия судна. Инсталляционные файлы приложения.

    курсовая работа [4,0 M], добавлен 26.12.2011

  • Создание клиент-серверного приложения на основе технологии CORBA. Проектирование многоуровневой системы, в которой клиент при помощи банкомата выполняет необходимые операции. Способы реализации серверов в разных каналах для ускорения обработки данных.

    лабораторная работа [1,1 M], добавлен 08.06.2009

  • Характеристика разновидностей программной реализации чатов. Разработка программы клиент-серверного чата с возможность общения в локальной сети нескольких человек одновременно. Протокол взаимодействия клиента и сервера. Порядок работы с программой.

    курсовая работа [530,7 K], добавлен 25.04.2015

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.