-
Notifications
You must be signed in to change notification settings - Fork 0
/
servercommunication.cpp
107 lines (90 loc) · 3.04 KB
/
servercommunication.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
/**
* @file servercommunication.cpp
* @brief ServerCommunication class source file
*
* This class is responsible for sending/receiving
* messages from/to clients. It owns the
* tcp server object and the clients sockets.
*
* @author Fedi Salhi
* @date December 22 2022
*
*/
#include "servercommunication.h"
ServerCommunication::ServerCommunication(const QHostAddress& address, quint16 port)
{
this->_server = new QTcpServer();
if(!(this->_server->listen(address, port))) {
this->_listenStatus = ServerStatus::kServerListenFailure;
} else {
this->_listenStatus = ServerStatus::kServerListenSuccess;
}
connect(this->_server, SIGNAL(newConnection()), this, SLOT(newConnectionEstablished()));
this->messageSize = 0;
}
void ServerCommunication::newConnectionEstablished() {
sendToAll("New client connected!");
QTcpSocket* newClient = this->_server->nextPendingConnection();
this->_clients.append(newClient);
connect(newClient, SIGNAL(readyRead()), this, SLOT(newDataReceived()));
connect(newClient, SIGNAL(disconnected()), this, SLOT(clientDisconnected()));
}
void ServerCommunication::newDataReceived() {
QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
// sender not known, just return
return;
}
QDataStream in(socket);
if (this->messageSize == 0) {
// if we still don't know the size of the message, try to capture it
if (socket->bytesAvailable() < (int)sizeof(quint16)) {
// we still didn't get the size, just return
return;
}
in >> this->messageSize;
// we captured the size of the message, let's capture the message now
if (socket->bytesAvailable() < messageSize) {
// we didn't yet received all tcp sub-packages, just return
return;
}
// the message is entirely received
QString message;
in >> message;
sendToAll(message);
this->messageSize = 0; // reset the message size for the new message
}
}
void ServerCommunication::clientDisconnected() {
sendToAll("A client just disconnected");
QTcpSocket* socket = qobject_cast<QTcpSocket*>(sender());
if (!socket) {
return;
} else {
this->_clients.removeOne(socket);
socket->deleteLater(); // don't use delet client, deleting the source of the signal may cause a problem later
}
}
void ServerCommunication::sendToAll(const QString& message) {
QByteArray package;
QDataStream out(&package, QIODevice::WriteOnly);
out << (quint16)0;
out << message;
out.device()->seek(0);
out << (quint16)(package.size()-sizeof(quint16));
for(auto* item : _clients) {
item->write(package);
}
}
ServerCommunication::~ServerCommunication() {
delete this->_server;
for(auto* item : this->_clients) {
delete item;
}
}
ServerStatus ServerCommunication::ServerListenStatus() {
return this->_listenStatus;
}
quint8 ServerCommunication::getNumberClients() {
return _clients.size();
}