Исходный текст сервера
myserver.h
#ifndef MYSERVER_H
#define MYSERVER_H
#include <QTcpServer>
#include <mutex>
#include <utility>
#include <fstream>
#include <iostream>
#include "mythread.h"
typedef std::vector<double> vect;
class MyServer : public QTcpServer
{
Q_OBJECT
public:
explicit MyServer(QObject *parent = 0);
void startServer();
void Generatemtx(std::vector<vect>* newmtx, int size);
signals:
void JobIsDone();
void DoTask();
public slots:
void ManageTask(qintptr ID, MyThread *request);
void TaskIsDone(qintptr ID);
void Reschedule(qintptr ID);
protected:
void incomingConnection(qintptr socketDescriptor);
void Closing();
int *currentNum;
int size = 20;
std::mutex flag, flag2;
std::vector<vect> fstmtx, scndmtx;
std::vector<QByteArray> finalmtx;
std::vector<std::pair<qintptr,int>> TaskTable;
std::vector<int> TaskBar;
};
#endif // MYSERVER_H
myserver.cpp
#include "myserver.h"
MyServer::MyServer(QObject *parent) :
QTcpServer(parent)
{
currentNum = new int;
*currentNum = 0;
Generatemtx(&fstmtx,size);
Generatemtx(&scndmtx,size);
for(int i=0; i<size; i++)
{
finalmtx.push_back(*(new QByteArray));
TaskBar.push_back(size-1-i);
}
}
void MyServer::startServer()
{
int port = 1234;
if(!this->listen(QHostAddress::Any, port))
{
qDebug() << "Could not start server";
}
else
{
qDebug() << "Listening to port " << port << "...";
}
}
// This function is called by QTcpServer when a new connection is available.
void MyServer::incomingConnection(qintptr socketDescriptor)
{
std::pair<qintptr,int> newTread;
newTread.first = socketDescriptor;
newTread.second = 0;
TaskTable.push_back(newTread);
// We have a new connection
qDebug() << socketDescriptor << " Connecting...";
// Every new connection will be run in a newly created thread
MyThread *thread = new MyThread(&fstmtx,&scndmtx,&finalmtx,currentNum, size, socketDescriptor, this);
// connect signal/slot
// once a thread is not needed, it will be beleted later
qRegisterMetaType<qintptr>("qintptr");
qRegisterMetaType<MyThread*>("MyThread*");
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
//connecting different signals from threads
connect(thread,SIGNAL(IWantATask(qintptr, MyThread*)),this,SLOT(ManageTask(qintptr, MyThread*)));
connect(thread,SIGNAL(TaskIsDone(qintptr)),this,SLOT(TaskIsDone(qintptr)));
connect(thread,SIGNAL(TreadDisconnected(qintptr)),this,SLOT(Reschedule(qintptr)),Qt::QueuedConnection);
thread->start();
}
void MyServer::Generatemtx(std::vector<vect>* newmtx, int size1)
{
double newnum = 0;
std::vector<double> newvec;
for(int i=0; i<size1; i++){
for(int j=0; j<size1; j++){
newnum = rand()%10;
newvec.push_back(newnum);
}
(*newmtx).push_back(newvec);
newvec.clear();
}
}
void MyServer::Closing()
{
this->close();
qDebug()<<"Job is done.Server stopped.";
for (unsigned int i=0;i<finalmtx.size();i++)
qDebug()<<finalmtx[i];
exit(0);
}
void MyServer::ManageTask(qintptr ID, MyThread *request)
{
if(TaskBar.empty())
//If there are no tasks for client - we may stop thread and close its socket
{
qDebug() << "Job is Done!";
flag2.lock();
for(unsigned int i = 0; i<TaskTable.size(); i++)
{
if(TaskTable[i].first==ID)
{
TaskTable.erase(TaskTable.begin()+i);
}
}
request->exit(0);
flag2.unlock();
//If there are no other working threads - we may stop server
if(TaskTable.empty())
{
qDebug()<<"Closing...";
this->Closing();
}
}
else
{
//There are tasks - we need to give one to the calling thread
for(unsigned int i = 0; i<TaskTable.size(); i++)
{
if(TaskTable[i].first==ID)
{
flag.lock();
TaskTable[i].second = TaskBar[TaskBar.size()-1];
TaskBar.pop_back();
*currentNum = TaskTable[i].second;
qDebug()<<"New task: " << *currentNum;
flag.unlock();
break;
}
}
request->Unlock();
}
}
void MyServer::TaskIsDone(qintptr ID)
{
for(unsigned int i = 0; i<TaskTable.size(); i++)
{
if(TaskTable[i].first==ID)
{
flag.lock();
TaskTable[i].second=-1;
qDebug()<<ID<<": Task is done";
flag.unlock();
break;
}
}
}
//Rescheduling TaskBar after client's disconnection
void MyServer::Reschedule(qintptr ID)
{
flag2.lock();
qDebug() <<"Rescheduling...";
for(unsigned int i = 0; i<TaskTable.size(); i++)
{
if(TaskTable[i].first==ID)
{
if(TaskTable[i].second!=-1)
{
TaskBar.push_back(TaskTable[i].second);
}
TaskTable.erase(TaskTable.begin()+i);
}
}
flag2.unlock();
}
mythread.h
#ifndef MYTHREAD_H
#define MYTHREAD_H
#include <QThread>
#include <QTcpSocket>
#include <QDebug>
#include <condition_variable>
typedef std::vector<double> vect;
class MyThread : public QThread
{
Q_OBJECT
public:
explicit MyThread(std::vector<vect>* fst,std::vector<vect>* scnd,std::vector<QByteArray>* final,int *_currentNum,int, qintptr ID, QObject *parent = 0);
void run();
int* currentNum;
int size;
int* globalcounter;
std::vector<int> next;
std::vector<vect>* fstmtx;
std::vector<vect>* scndmtx;
std::vector<QByteArray>* finalmtx;
signals:
void error(QTcpSocket::SocketError socketerror);
void JobIsDone();
void IWantATask(qintptr, MyThread*);
void TaskIsDone(qintptr);
void TreadDisconnected(qintptr);
public slots:
void readyRead();
void disconnected();
void Closesocket();
void DoTask();
void Unlock();
private:
QObject *Myparent;
QTcpSocket *socket;
qintptr socketDescriptor;
std::condition_variable stoppoint;
std::mutex g_lock;
};
#endif // MYTHREAD_H
mythread.cpp
#include "mythread.h"
MyThread::MyThread(std::vector<vect>* fst,std::vector<vect>* scnd,std::vector<QByteArray>* final,int* _currentNum, int _size, qintptr ID, QObject *parent ) :
QThread(parent)
{
this->socketDescriptor = ID;
currentNum = _currentNum;
Myparent = parent;
fstmtx = fst;
scndmtx = scnd;
finalmtx = final;
size = _size;
globalcounter = new int;
*globalcounter = 0;
}
void MyThread::run()
{
// thread starts here
qDebug() << " Thread started";
socket = new QTcpSocket();
// set the ID
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
// something's wrong, we just emit a signal
emit error(socket->error());
return;
}
// connect socket and signal
// note - Qt::DirectConnection is used because it's multithreaded
//This makes the slot to be invoked immediately, when the signal is emitted.
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
// We'll have multiple clients, we want to know which is which
qDebug() << socketDescriptor << " Client connected";
// make this thread a loop,
// thread will stay alive so that signal/slot to function properly
// not dropped out in the middle when thread dies
exec();
disconnect(socket, 0, 0, 0);
this->Closesocket();
}
void MyThread::readyRead()
{
// get the information
std::unique_lock<std::mutex> locker(g_lock);
QByteArray Data = socket->readAll();
int Index = 0;
if (Data.indexOf("Index:")!=-1)
{
bool ok;
Index = Data.mid(6,Data.indexOf("Vector:")-6).toInt(&ok, 10);
(*finalmtx)[Index] = Data.mid(Data.indexOf("Vector:")+7,Data.size()-Data.indexOf("Vector:")-16);
}
//emit signal requiring task
this->IWantATask(socketDescriptor, this);
stoppoint.wait(locker);
QTextStream os(socket);
os.setAutoDetectUnicode(true);
os<<"Second:";
for(unsigned int i=0; i<(*scndmtx).size();i++)
{
for(unsigned int j=0; j<(*scndmtx).size();j++)
os<< ((*scndmtx)[i][j]);
os<<"_";
}
os<<"First:";
for(unsigned int i=0; i<(*fstmtx).size();i++)
os<<((*scndmtx)[*currentNum][i]);
os<<"Info: "<<(*currentNum);
socket->waitForBytesWritten(2000);
}
void MyThread::DoTask()
{
}
void MyThread::disconnected()
{
qDebug() << socketDescriptor << " Disconnected";
disconnect(socket, 0, 0, 0);
this->TreadDisconnected(socketDescriptor);
socket->deleteLater();
exit(0);
}
void MyThread::Closesocket()
{
socket->deleteLater();
}
void MyThread::Unlock()
{
stoppoint.notify_one();
}
main.cpp
#include <QCoreApplication>
#include "myserver.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
// Make a server and start it
MyServer server;
server.startServer();
return a.exec();
}
Исходный текст клиента
mytcpsocket.h
#ifndef MYTCPSOCKET_H
#define MYTCPSOCKET_H
#include <QObject>
#include <QTcpSocket>
#include <QDebug>
#include <thread>
#include <iostream>
#include <fstream>
typedef std::vector<double> vect;
class MyTcpSocket : public QObject
{
Q_OBJECT
public:
explicit MyTcpSocket(QObject *parent = 0);
void doConnect();
std::vector<vect> Convert(QByteArray mtx, int size);
std::vector<double> Convert(QByteArray mtx);
signals:
public slots:
void readyRead();
void disconnected();
private:
QTcpSocket *socket;
QTextStream os;
QString data;
qint64 size, toberead;
QByteArray newdata;
};
#endif // MYTCPSOCKET_H
mytcpsocket.cpp
#include "mytcpsocket.h"
MyTcpSocket::MyTcpSocket(QObject *parent) :
QObject(parent)
{
}
void MyTcpSocket::doConnect()
{
socket = new QTcpSocket(this);
socket->connectToHost("localhost", 1234);
if(socket->waitForConnected(5000))
{
qDebug()<<"Connected!";
}
else
{
qDebug()<<"Not connected!";
}
os.setDevice(socket);
os<<"Hello, server!";
os.flush();
socket->waitForBytesWritten(1000);
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()));
}
void MyTcpSocket::readyRead()
{
double summ = 0;
while(newdata!="Job is done!")
{
socket->waitForReadyRead(3000);
qDebug()<<"Reading: "<<socket->bytesAvailable();;
newdata = socket->readAll();
if(newdata!="Job is done!")
{
double finalIndex = newdata.mid(newdata.indexOf("Info:")+6).toDouble();
qDebug()<<"Final index: "<<finalIndex;
QByteArray mtx2 = newdata.mid(newdata.indexOf("Second:")+7,newdata.indexOf("First:")-7);
QByteArray mtx1 = newdata.mid(newdata.indexOf("First:")+6,newdata.indexOf("Info")-newdata.indexOf("First:")-6);
std::vector<vect> mtx2double = Convert(mtx2,mtx1.size());
std::vector<double> mtx1double = Convert(mtx1);
std::ofstream ofs ("test.txt", std::ofstream::app);
for(unsigned int i=0; i<mtx2double.size(); i++)
{
for(unsigned int j=0; j<mtx2double.size();j++)
ofs<<mtx2double[i][j]<<" ";
ofs<<std::endl;
}
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
ofs<<"counting:"<<std::endl;
ofs<<"Index:"<<finalIndex;
os<<"Index:"<<finalIndex;
ofs<<"Vector:";
os<<"Vector:";
for(unsigned int i=0; i<mtx1double.size(); i++)
{
for(unsigned int j=0; j<mtx1double.size(); j++)
{
summ+=mtx1double[j]*mtx2double[j][i];
}
os<<summ<<" ";
summ = 0;
}
ofs<<std::endl;
os<<"\nCounted!";
os.flush();
socket->waitForBytesWritten(1000);
}
else
{
os<<"Finished";
os.flush();
socket->waitForBytesWritten(1000);
}
}
qDebug()<<"Job is done!";
socket->close();
}
std::vector<vect> MyTcpSocket::Convert(QByteArray mtx, int size)
{
QByteArray newsign;
int k = 0;
std::vector<vect> newmtx;
std::vector<double> newvec;
for(int i=0; i<size; i++){
for(int j=0; j<size; j++){
newsign.append(mtx[k]);
newvec.push_back(newsign.toDouble());
k++;
newsign.clear();
}
newmtx.push_back(newvec);
newvec.clear();
k++;
}
return newmtx;
}
std::vector<double> MyTcpSocket::Convert(QByteArray mtx)
{
QByteArray newsign;
std::vector<double> newvec;
for(int i=0; i<mtx.size(); i++)
{
newsign.append(mtx[i]);
newvec.push_back(newsign.toDouble());
newsign.clear();
}
return newvec;
}
void MyTcpSocket::disconnected()
{
qDebug() << " Disconnected";
newdata = socket->readAll();
qDebug() << newdata;
socket->deleteLater();
exit(0);
}
main.cpp
#include <QCoreApplication>
#include "mytcpsocket.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
MyTcpSocket s;
s.doConnect();
return a.exec();
}