1 #include "tcpnetwork.h"
3 #include "../structures/header.h"
5 using namespace network;
6 using namespace enc_hash;
7 using namespace structures;
10 //Tcp server implementation
11 tcpServer::tcpServer(quint64 buffersize, QObject *parent):QTcpServer(parent){this->buffersize=buffersize;}
13 void tcpServer::incomingConnection(int handle){
14 threadedTcpSocket *socket=new threadedTcpSocket(this->buffersize,this);
15 connect(socket,SIGNAL(pending()),SLOT(socket_pending()));
16 socket->socketDescriptor(handle);
18 emit this->newConnection();
20 bool tcpServer::socket_pending(){
22 server_msg<<"CALL:socket_pending";
24 threadedTcpSocket *socket=qobject_cast<threadedTcpSocket *>(this->sender());
25 if(!emit this->pending(AddressAndPort(socket->peerAddr().first,socket->peerAddr().second))){
27 server_msg<<"A client accessed, but refused because user didn't accept.";
31 emit this->socket_accepted(*socket);
35 //Tcp socket implementation
36 tcpSocket::tcpSocket(const quint64 buffersize, QObject *parent):QTcpSocket(parent){
37 this->buffer_size=buffersize;
39 this->event=tcpSocket::Size;
40 connect(this,SIGNAL(readyRead()),SLOT(read_data()));
41 connect(this,SIGNAL(bytesWritten(qint64)),SLOT(move_next_section(const qint64)));
42 connect(this,SIGNAL(disconnected()),SLOT(deleteLater()));
43 connect(this,SIGNAL(error(QAbstractSocket::SocketError)),SLOT(error_occured(QAbstractSocket::SocketError)));
45 server_msg<<"tcpSocket is constructed.";
47 server_msg<<"blocked:"<<this->signalsBlocked();
50 void tcpSocket::read_data(){
51 /*TODO: remove this loop*/
52 while(this->bytesAvailable()>=0){
54 server_msg<<"server Event Mode:"<<this->event;
55 server_msg<<"server Available bytes:"<<this->bytesAvailable();
58 case tcpSocket::Size: this->size_event(); break;
59 case tcpSocket::Header: this->header_event(); break;
60 case tcpSocket::Msg: this->msg_event(); break;
61 case tcpSocket::File: this->file_event(); break;
62 default: this->disconnectFromHost(); return;
66 void tcpSocket::move_next_section(const qint64 size){
69 case tcpSocket::Size: this->event=tcpSocket::Header; break;
70 case tcpSocket::Header:
71 this->event=(this->head_data.fileName().isEmpty()?tcpSocket::Msg:tcpSocket::File);
74 this->event=tcpSocket::End;
78 void tcpSocket::send_flag(const Flag flag){
80 send_data.append((int)flag);
81 this->write(send_data);
83 this->setErrorString(tr("Accept signal couldn't be sent."));
84 emit this->error(QAbstractSocket::UnknownSocketError);
88 server_msg<<"the flag:"<<flag<<" has been sent.";
92 void tcpSocket::size_event(){
93 if(this->bytesAvailable()<2) return;
95 this->read(size_buf,sizeof(size_buf));
96 memcpy(&this->header_size,size_buf,
97 (sizeof(quint16)>sizeof(size_buf))?sizeof(quint16):sizeof(size_buf)
99 //this->send_flag(tcpSocket::accepted);
100 this->move_next_section(0);
102 void tcpSocket::header_event(){
103 if(this->bytesAvailable()<this->header_size) return;
105 QByteArray data=this->read(this->header_size);
106 QDataStream datastream(data);
107 datastream>>this->head_data;
108 if(this->head_data==structures::header()){
109 this->setErrorString(tr("The header is empty."));
110 emit this->error(QAbstractSocket::UnknownSocketError);
111 this->disconnectFromHost();
114 if(!this->head_data.fileName().isEmpty()){
115 this->where_to_save=(emit this->file_pending());
116 if(this->where_to_save.isEmpty()){
117 this->write(QByteArray(1,0x00));
119 this->setErrorString(tr("The filename is empty."));
120 emit this->error(QAbstractSocket::UnknownSocketError);
122 this->disconnectFromHost();
126 emit this->header_received();
128 //this->send_flag(tcpSocket::accepted);
129 this->move_next_section(0);
131 void tcpSocket::msg_event(){
132 if((quint64)this->bytesAvailable()<this->header_data().datasize()) return;
133 quint64 final_readsize=this->head_data.datasize()%this->buffer_size,
134 read_count=(this->head_data.datasize()-final_readsize)/this->buffer_size;
136 for(quint64 count=0;count<read_count;count++){
137 if(this->check_canceled())return;
138 msg+=this->read(this->buffer_size);
140 if(this->check_canceled())return;
141 msg+=this->read(final_readsize);
144 if(this->head_data.ripemd160()==generator.compute_hash(msg)){
145 emit this->msg_received(QString::fromUtf8(msg.data()));
149 qDebug()<<"Hash digest error. the received message may be broken or modified.";
150 qDebug()<<"this->head_date.ripemd160():"<<this->head_data.ripemd160();
151 qDebug()<<"RIPEMD160-Hash"<<generator.compute_hash(msg);
153 this->setErrorString(tr("The data has been broken."));
154 emit this->error(QAbstractSocket::UnknownSocketError);
156 //this->send_flag(tcpSocket::accepted);
157 this->move_next_section(0);
159 void tcpSocket::file_event(){
160 if((quint64)this->bytesAvailable()<this->header_data().datasize()) return;
161 quint64 final_readsize=this->head_data.datasize()%this->buffer_size,
162 read_count=(this->head_data.datasize()-final_readsize)/this->buffer_size;
164 if(this->where_to_save.isEmpty()){
165 this->setErrorString(tr("The filename is empty."));
166 emit this->error(QAbstractSocket::UnknownSocketError);
167 this->disconnectFromHost();
170 QFile file(this->where_to_save,this);
171 if(!file.open(QIODevice::Truncate|QIODevice::WriteOnly)){
172 this->where_to_save=emit this->fileStream_openFailed(file.error(),file.errorString());
175 for(quint64 count=0;count<read_count&&!this->check_canceled();count++){
176 if(this->check_canceled())return;
177 file.write(this->read(this->buffer_size));
178 emit this->file_receive_progress(file.pos());
180 if(this->check_canceled())return;
181 file.write(this->read(final_readsize));
182 emit this->file_receive_progress(file.pos());
186 if(this->head_data.ripemd160()==generator.compute_hash(file))
187 emit this->file_saved();
189 this->setErrorString(tr("The file has been broken."));
190 emit this->error(QAbstractSocket::UnknownSocketError);
192 //this->send_flag(tcpSocket::accepted);
193 this->move_next_section(0);
195 void threadedTcpSocket::header_received(){
196 tcpSocket *socket=qobject_cast<tcpSocket *>(this->sender());
197 this->locks[threadedTcpSocket::HeaderData].lockForWrite();
198 this->_header=socket->header_data();
199 this->locks[threadedTcpSocket::HeaderData].unlock();
202 //Threaded TCP socket (for server) implemantation
203 threadedTcpSocket::threadedTcpSocket(const quint64 buffersize, QObject *parent):QThread(parent){
204 connect(this,SIGNAL(finished()),SLOT(deleteLater()));
205 connect(this,SIGNAL(terminated()),SLOT(deleteLater()));
206 this->locks[threadedTcpSocket::Mode].lockForWrite();
207 this->locks[threadedTcpSocket::BufferSize].lockForWrite();
208 this->locks[threadedTcpSocket::RWMode].lockForWrite();
209 this->mode=threadedTcpSocket::Session;
210 this->_buffersize=buffersize;
211 this->open_mode=QAbstractSocket::ReadWrite;
212 this->locks[threadedTcpSocket::Mode].unlock();
213 this->locks[threadedTcpSocket::BufferSize].unlock();
214 this->locks[threadedTcpSocket::RWMode].unlock();;