1 #include "tcpnetwork.h"
3 #include "../structures/header.h"
5 using namespace network;
6 using namespace enc_hash;
7 using namespace structures;
10 //Tpc server implementation
11 tcpServer::tcpServer(quint64 buffersize, QObject *parent):QTcpServer(parent){this->buffersize=buffersize;}
13 void tcpServer::incomingConnection(int handle){
14 tcpSocket *socket=new tcpSocket(this->buffersize,this);
15 if(!socket->setSocketDescriptor(handle)){
16 emit this->socket_error(*socket);
19 if(emit this->pending(*socket)) this->newConnection();
23 //Tcp socket implementation
24 tcpSocket::tcpSocket(const quint64 buffersize, QObject *parent):QTcpSocket(parent){
25 this->buffer_size=buffersize;
27 this->event=tcpSocket::headsize;
28 connect(this,SIGNAL(disconnected()),SLOT(deleteLater()));
29 connect(this,SIGNAL(readyRead()),SLOT(read_data()));
31 qDebug()<<"TcpSocket is constructed.";
33 qDebug()<<"Blocked:"<<this->signalsBlocked();
36 tcpSocket::tcpSocket(const QString &senderName,const quint64 buffersize,QObject *parent):QTcpSocket(parent){
37 this->buffer_size=buffersize;
38 this->senderName=senderName;
41 void tcpSocket::read_data(){
42 while(this->bytesAvailable()>0){
44 qDebug()<<"Server Event Mode:"<<this->event<<"Server Available bytes:"<<this->bytesAvailable();
47 case tcpSocket::headsize: this->size_event(); break;
48 case tcpSocket::header_receive: this->header_event(); break;
49 case tcpSocket::msg: this->msg_event(); break;
50 case tcpSocket::file: this->file_event(); break;
54 void tcpSocket::size_event(){
55 if(this->bytesAvailable()<2) return;
57 this->read(size_buf,sizeof(size_buf));
58 memcpy(&this->header_size,size_buf,
59 (sizeof(quint16)>sizeof(size_buf))?sizeof(quint16):sizeof(size_buf)
61 this->event=tcpSocket::header_receive;
63 void tcpSocket::header_event(){
64 if(this->bytesAvailable()<this->header_size) return;
66 QByteArray data=this->read(this->header_size);
67 QDataStream datastream(data);
68 datastream>>this->head_data;
69 if(this->head_data==structures::header()){
70 this->setErrorString(tr("The header is empty."));
71 emit this->error(QAbstractSocket::UnknownSocketError);
72 this->disconnectFromHost();
75 if(!this->head_data.fileName().isEmpty()){
76 this->where_to_save=(emit this->file_pending());
77 if(this->where_to_save.isEmpty()){
78 this->write(QByteArray(1,0x00));
80 this->setErrorString(tr("The filename is empty."));
81 emit this->error(QAbstractSocket::UnknownSocketError);
83 this->disconnectFromHost();
88 if(this->head_data.fileName().isEmpty()) this->event=tcpSocket::msg;
89 else this->event=tcpSocket::file;
91 void tcpSocket::msg_event(){
92 if((quint64)this->bytesAvailable()<this->header_data().datasize()) return;
93 quint64 final_readsize=this->head_data.datasize()%this->buffer_size,
94 read_count=(this->head_data.datasize()-final_readsize)/this->buffer_size;
96 for(quint64 count=0;count<read_count;count++){
97 if(this->check_canceled_then_abort())return;
98 msg+=this->read(this->buffer_size);
100 if(this->check_canceled_then_abort())return;
101 msg+=this->read(final_readsize);
104 if(this->head_data.ripemd160()==generator.compute_hash(msg))
105 emit this->msg_received(QString::fromUtf8(msg.data()));
107 this->setErrorString(tr("The data has been broken."));
108 emit this->error(QAbstractSocket::UnknownSocketError);
110 this->disconnectFromHost();
112 void tcpSocket::file_event(){
113 if((quint64)this->bytesAvailable()<this->header_data().datasize()) return;
114 quint64 final_readsize=this->head_data.datasize()%this->buffer_size,
115 read_count=(this->head_data.datasize()-final_readsize)/this->buffer_size;
117 if(this->where_to_save.isEmpty()){
118 this->setErrorString(tr("The filename is empty."));
119 emit this->error(QAbstractSocket::UnknownSocketError);
120 this->disconnectFromHost();
123 QFile file(this->where_to_save,this);
124 if(!file.open(QIODevice::Truncate|QIODevice::WriteOnly)){
125 this->where_to_save=emit this->fileStream_openFailed(file.error(),file.errorString());
128 for(quint64 count=0;count<read_count&&!this->check_canceled_then_abort();count++){
129 if(this->check_canceled_then_abort())return;
130 file.write(this->read(this->buffer_size));
131 emit this->file_receive_progress(file.pos());
133 if(this->check_canceled_then_abort())return;
134 file.write(this->read(final_readsize));
135 emit this->file_receive_progress(file.pos());
139 if(this->head_data.ripemd160()==generator.compute_hash(file))
140 emit this->file_saved();
142 this->setErrorString(tr("The file has been broken."));
143 emit this->error(QAbstractSocket::UnknownSocketError);
145 this->disconnectFromHost();
148 bool tcpSocket::check_canceled_then_abort(){
150 this->setErrorString(tr("The process has been canceled by user."));
151 emit this->error(QAbstractSocket::UnknownSocketError);
157 void tcpSocket::disconnectFromHostImplementation(){
159 QTcpSocket::disconnectFromHost();
161 tcpSocket &tcpSocket::operator<<(const QString &msg){
162 if(this->state()!=QAbstractSocket::ConnectedState) return (*this);
163 this->head_data=header(this->senderName,msg);
164 QByteArray tmp_buffer;
165 QDataStream datastream(&tmp_buffer,QIODevice::WriteOnly);
166 datastream<<this->head_data;
167 quint16 size=(quint16)tmp_buffer.size();
168 this->write((char*)&size,sizeof(size)/sizeof(char));
169 if(!this->flush())return (*this);
170 this->write(tmp_buffer);
171 if(!this->flush())return (*this);
173 tmp_buffer=msg.toUtf8();
174 QBuffer memoryStream(&tmp_buffer,this);
175 if(!memoryStream.open(QIODevice::ReadOnly)){
176 this->setErrorString(tr("Memory Stream couldn't open."));
177 emit this->error(QAbstractSocket::UnknownSocketError);
180 while(this->write(memoryStream.read(this->buffer_size))>0)
181 if(!this->flush())return (*this);
182 memoryStream.close();
184 emit this->sentData();
187 tcpSocket &tcpSocket::operator<<(const QFileInfo &src_file){
188 QtLockedFile file(src_file.fileName());
189 if(!this->state()!=QAbstractSocket::ConnectedState)return (*this);
190 this->head_data=header(this->senderName,QFileInfo(file));
191 QByteArray tmp_buffer;
192 QDataStream datastream(tmp_buffer);
193 quint16 size=(quint16)tmp_buffer.size();
194 datastream<<this->head_data;
195 this->write((char*)&size,sizeof(size)/sizeof(char));
196 if(!this->flush())return (*this);
197 this->write(tmp_buffer);
198 if(!this->flush())return (*this);
200 emit this->file_header_sent();
201 if(!file.open(QIODevice::ReadOnly)){
202 this->setErrorString(tr("The file stream couldn't open."));
203 emit this->error(QAbstractSocket::UnknownSocketError);
206 file.lock(QtLockedFile::ReadLock);
207 while(this->write(file.read(this->buffer_size))>0&&!this->check_canceled_then_abort()){
208 if(!this->flush())return (*this);
209 emit this->sending_file_progress(file.pos());
213 emit this->sentData();
216 void tcpSocket::cancel(){this->canceled=true;}
217 QString tcpSocket::path_to_save() const{return this->where_to_save;}
218 header tcpSocket::header_data() const{return this->head_data;}