// protocol.h
#ifndef PROTOCOL_H
#define PROTOCOL_H
#include <QtNetwork>
// myproto Thread class
Q_OBJECT
public:
// Constructor
// Destructor
~Protocol();
// The Socket pointer
QSslSocket * socket;
// Variables for logging in etc
QMap<QString, QString> vars;
unsigned int bblen; // The len of data in the bbuffer
int Compress; // Is the current partition to be compressed ?
unsigned int written; // How many packets have been written
unsigned int maxtx; // The amount of packets that can be written in one shot
int socket_rw_time; // The last time there was a socket read write
int sleepFor; // Will sleep for these many milliseconds
int doneCalled; // Is set to 1 or greater when done is called
QList<quint64> badBlocks; // Any bad blocks found
// Finish the backup process
void done();
// Write the data with the length header
qint64 rite
(const QByteArray & data,
bool keptAlive
= false);
// Start the process to backup - Issues the login command
bool doit();
// Send Data
void sendBlocks();
signals:
void quit();
void finished();
private slots:
// When any data is available, it goes through this
void socketReadyRead();
// Called when the Encryption starts over SSL Sockets
void socketEncrypted();
// More slots
};
#endif
// protocol.h
#ifndef PROTOCOL_H
#define PROTOCOL_H
#include <QtNetwork>
// myproto Thread class
class Protocol : public QObject {
Q_OBJECT
public:
// Constructor
Protocol(QObject *parent = 0);
// Destructor
~Protocol();
// The Socket pointer
QSslSocket * socket;
// Variables for logging in etc
QMap<QString, QString> vars;
unsigned int bblen; // The len of data in the bbuffer
int Compress; // Is the current partition to be compressed ?
unsigned int written; // How many packets have been written
unsigned int maxtx; // The amount of packets that can be written in one shot
int socket_rw_time; // The last time there was a socket read write
int sleepFor; // Will sleep for these many milliseconds
int doneCalled; // Is set to 1 or greater when done is called
QList<quint64> badBlocks; // Any bad blocks found
// Finish the backup process
void done();
// Write the data with the length header
qint64 rite (const QByteArray & data, bool keptAlive = false);
// Start the process to backup - Issues the login command
bool doit();
// Send Data
void sendBlocks();
signals:
void quit();
void finished();
private slots:
// When any data is available, it goes through this
void socketReadyRead();
// Called when the Encryption starts over SSL Sockets
void socketEncrypted();
// More slots
};
#endif
To copy to clipboard, switch view to plain text mode
// protocol.cpp
#include "protocol.h"
// The constructor
NULOG2("[Protocol::Protocol] Start");
// Codes
socket = new QSslSocket();
}
// Destructor
Protocol::~Protocol(){
NULOG2("[Protocol::~Protocol] Destructor");
delete socket;
}
// Finish the backup process, even in case of error
void Protocol::done(){
// Had to comment due to large post
}
// Socket write safe as it appends the length to the beginning of the string
qint64 Protocol
::rite(const QByteArray & data,
bool keptAlive
){ quint16 qlen = ((quint16)data.size());
qint64 w = socket->write(len + data);
NULOG4("[Protocol::rite] Size : " << data.size() << "Written : " << w);
return w;
}
// Start the whole process
bool Protocol::doit(){
// Get the kernel data
//this->myproto_config();
connect(socket, SIGNAL(readyRead()),
this, SLOT(socketReadyRead()));
connect(socket, SIGNAL(bytesWritten(qint64)),
this, SLOT(socketBytesWritten(qint64)));
connect(socket, SIGNAL(encryptedBytesWritten(qint64)),
this, SLOT(socketencryptedBytesWritten(qint64)));
connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(sslErrors(QList<QSslError>)));
/*connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));*/
// Encrypted
if(true){
NULOG1("[Protocol::doit] Connecting to Secure Server " << vars["hostname"] << "Port :" << vars["port"]);
connect(socket, SIGNAL(encrypted()),
this, SLOT(socketEncrypted()));
// Connect to the server
socket->connectToHostEncrypted(vars["hostname"], vars["port"].toInt());
}
return true;
}
// Called when the connection is fully established
void Protocol::socketEncrypted(){
NULOG1("[Protocol::socketEncrypted] Connection Established with Server");
// This is the myproto protocol
socket->write("myproto\r\n");
socket->waitForBytesWritten();
// We first need to LOGIN
this->rite("LOGIN "+ username.toBase64() +" "+ password.toBase64());
}
// Called whenever there is something to READ in the buffer
void Protocol::socketReadyRead(){
qint64 n;
int Packetlen;
while(socket->bytesAvailable() != 0){
// Find the length of the command
if (dlen == 0) {
if(socket->bytesAvailable() < 2){
NULOG2("[Protocol::socketReadyRead] Less than 2 packets...breaking" << socket->bytesAvailable());
break;
}
len = socket->read(2);
// Was there an error in reading ?
if(len.size() != 2){
NULOG0("[Protocol::socketReadyRead] Could not read the Length of the Packet " << len.size());
return;
}
dlen = (qint64)((((quint8)len[0]) << 8) | (quint8)len[1]);
// The packet cannot be greater than buffer
if(dlen > 8192){
NULOG0("[Protocol::socketReadyRead] The packet cannot be greater than buffer");
return;
}
}
// If there are not many bytes available then break
if(socket->bytesAvailable() < dlen){
break;
}
buf = socket->read(dlen);
// Is the packet of the right size
if(buf.size() != ((int)dlen)){
NULOG0("[Protocol::socketReadyRead] The bytes read" << n << "dont match the packet size" << dlen);
return;
}
// Clear the string
str = buf;
// Reset the counter
Packetlen = (int)dlen;
dlen = (qint64)0;
// Send data
if (str
[0].
toLower() == QChar('gd')){
sendBlocks();
// Quit
}else if (str
[0].
toLower() == QChar('qu')){
done();return;
// Unknown Command
}else{
NULOG0("[Protocol::socketReadyRead] An Unknown Command has happened");
}
}// End of while
}
// Sends the data to the server
void Protocol::sendBlocks(){
// Open File
QFile fp
("/path/to/large/file");
return false;
}
qint64 read = 0;
while(fp.size() != read){
// Write data
this->rite(finalData);
this->bblen++;
// Sleep to reduce read load
if((this->bblen % 2500) == 0 && this->bblen > 0){
NULOG2("[Protocol::sendBlocks] Bytes " << this->socket->encryptedBytesToWrite() << this->socket->bytesToWrite());
/*// The following CODE is used to flush data as for some reason the data is not flushed automatically
if((this->bblen % 25000) == 0){
while(this->socket->encryptedBytesToWrite() > 10000000 || this->socket->bytesToWrite() > 10000000){
this->socket->flush();
}
}*/
}
}
// Wait for more socket read !
return true;
}
// protocol.cpp
#include "protocol.h"
// The constructor
Protocol::Protocol(QObject *parent) : QObject(parent) {
NULOG2("[Protocol::Protocol] Start");
// Codes
socket = new QSslSocket();
}
// Destructor
Protocol::~Protocol(){
NULOG2("[Protocol::~Protocol] Destructor");
delete socket;
}
// Finish the backup process, even in case of error
void Protocol::done(){
// Had to comment due to large post
}
// Socket write safe as it appends the length to the beginning of the string
qint64 Protocol::rite(const QByteArray & data, bool keptAlive){
quint16 qlen = ((quint16)data.size());
QByteArray len;
len.append(QByteArray(((char*)&qlen)+1,1));
len.append(QByteArray((char*)&qlen,1));
qint64 w = socket->write(len + data);
NULOG4("[Protocol::rite] Size : " << data.size() << "Written : " << w);
return w;
}
// Start the whole process
bool Protocol::doit(){
// Get the kernel data
//this->myproto_config();
connect(socket, SIGNAL(readyRead()),
this, SLOT(socketReadyRead()));
connect(socket, SIGNAL(bytesWritten(qint64)),
this, SLOT(socketBytesWritten(qint64)));
connect(socket, SIGNAL(encryptedBytesWritten(qint64)),
this, SLOT(socketencryptedBytesWritten(qint64)));
connect(socket, SIGNAL(sslErrors(QList<QSslError>)),
this, SLOT(sslErrors(QList<QSslError>)));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
this, SLOT(serror(QAbstractSocket::SocketError)));
/*connect(socket, SIGNAL(stateChanged(QAbstractSocket::SocketState)),
this, SLOT(socketStateChanged(QAbstractSocket::SocketState)));*/
// Encrypted
if(true){
NULOG1("[Protocol::doit] Connecting to Secure Server " << vars["hostname"] << "Port :" << vars["port"]);
connect(socket, SIGNAL(encrypted()),
this, SLOT(socketEncrypted()));
// Connect to the server
socket->connectToHostEncrypted(vars["hostname"], vars["port"].toInt());
}
return true;
}
// Called when the connection is fully established
void Protocol::socketEncrypted(){
NULOG1("[Protocol::socketEncrypted] Connection Established with Server");
// This is the myproto protocol
socket->write("myproto\r\n");
socket->waitForBytesWritten();
QByteArray username = vars["username"].toUtf8();
QByteArray password = vars["password"].toUtf8();
// We first need to LOGIN
this->rite("LOGIN "+ username.toBase64() +" "+ password.toBase64());
}
// Called whenever there is something to READ in the buffer
void Protocol::socketReadyRead(){
QByteArray buf; // The buffer of the socket read
qint64 n;
QByteArray len;
QString str;
int Packetlen;
while(socket->bytesAvailable() != 0){
// Find the length of the command
if (dlen == 0) {
if(socket->bytesAvailable() < 2){
NULOG2("[Protocol::socketReadyRead] Less than 2 packets...breaking" << socket->bytesAvailable());
break;
}
len = socket->read(2);
// Was there an error in reading ?
if(len.size() != 2){
NULOG0("[Protocol::socketReadyRead] Could not read the Length of the Packet " << len.size());
return;
}
dlen = (qint64)((((quint8)len[0]) << 8) | (quint8)len[1]);
// The packet cannot be greater than buffer
if(dlen > 8192){
NULOG0("[Protocol::socketReadyRead] The packet cannot be greater than buffer");
return;
}
}
// If there are not many bytes available then break
if(socket->bytesAvailable() < dlen){
break;
}
buf = socket->read(dlen);
// Is the packet of the right size
if(buf.size() != ((int)dlen)){
NULOG0("[Protocol::socketReadyRead] The bytes read" << n << "dont match the packet size" << dlen);
return;
}
// Clear the string
str = buf;
// Reset the counter
Packetlen = (int)dlen;
dlen = (qint64)0;
// Send data
if (str[0].toLower() == QChar('gd')){
sendBlocks();
// Quit
}else if (str[0].toLower() == QChar('qu')){
done();return;
// Unknown Command
}else{
NULOG0("[Protocol::socketReadyRead] An Unknown Command has happened");
}
}// End of while
}
// Sends the data to the server
void Protocol::sendBlocks(){
// Open File
QFile fp("/path/to/large/file");
if(!fp.open(QIODevice::ReadOnly)){
return false;
}
qint64 read = 0;
while(fp.size() != read){
QByteArray finalData = fp.read(4096);
// Write data
this->rite(finalData);
this->bblen++;
// Sleep to reduce read load
if((this->bblen % 2500) == 0 && this->bblen > 0){
NULOG2("[Protocol::sendBlocks] Bytes " << this->socket->encryptedBytesToWrite() << this->socket->bytesToWrite());
/*// The following CODE is used to flush data as for some reason the data is not flushed automatically
if((this->bblen % 25000) == 0){
while(this->socket->encryptedBytesToWrite() > 10000000 || this->socket->bytesToWrite() > 10000000){
this->socket->flush();
}
}*/
}
}
// Wait for more socket read !
return true;
}
To copy to clipboard, switch view to plain text mode
Bookmarks