Repository navigation
Expand file tree
/
Copy pathclient.cpp
More file actions
205 lines (179 loc) · 6.46 KB
/
Copy pathclient.cpp
File metadata and controls
205 lines (179 loc) · 6.46 KB
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
#include "client.h"
#include <QApplication>
#include <QNetworkInterface>
Client::Client(QObject *parent)
: QObject(parent), serverAddress(QString("127.0.0.1")), serverPort(5000),
clientPort(5001), clientServer(clientPort, this),
serverConnection(clientInfo, rsa, this), nextId(0) {
if (!initialize()) {
qDebug() << "could not initialize rsa";
return;
}
foreach (const QHostAddress &address, QNetworkInterface::allAddresses()) {
if (address.protocol() == QAbstractSocket::IPv4Protocol &&
address != QHostAddress(QHostAddress::LocalHost))
clientInfo.clientAddress = address.toString();
}
connect(&clientServer, SIGNAL(incomingConnectionSignal(quintptr)), this,
SLOT(incomingConnection(quintptr)));
connect(&serverConnection, SIGNAL(onRegistrationReply(QString, QString)),
this, SLOT(registrationReplyReceived(QString, QString)));
connect(&serverConnection, SIGNAL(onUpdatedActiveClients(QJsonArray)), this,
SLOT(updatedActiveClients(QJsonArray)));
connect(&serverConnection, SIGNAL(onRequestReceived(ClientInfo)), this,
SLOT(receiveCreateChannelRequest(ClientInfo)));
connect(&serverConnection,
SIGNAL(onChannelReplyReceived(ClientInfo, bool, int)), this,
SLOT(receiveCreateChannelReply(ClientInfo, bool, int)));
serverConnection.connectToServer(serverAddress, serverPort);
serverConnection.sendSymKey();
}
const QList<QString> *Client::getActiveClients() { return &activeClients; }
void Client::sendCreateChannelRequest(QString name) {
serverConnection.sendCreateChannelRequest(name);
}
void Client::receiveCreateChannelRequest(ClientInfo clInfo) {
qDebug() << "received create channel request";
pendingConnections.push_back(clInfo);
if (pendingConnections.size() == 1) {
emit onChannelRequestReceived(clInfo.name);
}
}
void Client::sendMessage(QString dest, QString text) {
qDebug() << "sending message";
foreach (Channel *channel, activeChannels) {
if (channel->getOtherClientName() == dest) {
channel->sendMessage(text);
return;
}
}
// open channel for client not found, which means inconsistenct between our UI
// and client class.
qWarning() << "client not found\n";
}
void Client::registerToServer(QString name) {
serverConnection.sendRegistrationRequest(name);
}
void Client::incomingConnection(quintptr socketDescriptor) {
qDebug() << "incoming connection by connecting to client server on port: "
<< socketDescriptor;
// here we have to somehow verify whether the host attemptint to connect is
// the host that we accepted the request from
Channel *channel = new Channel(&expectingConnections, &expectingIds,
socketDescriptor, true, rsa, this);
connect(channel, SIGNAL(onMessageReceived(QString, QString)), this,
SLOT(messageReceived(QString, QString)));
connect(channel, SIGNAL(onChannelActive(QString)), this,
SLOT(channelActive(QString)));
connect(channel, SIGNAL(channelRemove(QString)), this,
SLOT(leaveChannel(QString)));
activeChannels.push_back(channel);
}
void Client::messageReceived(QString text, QString otherClient) {
emit onMessageReceivedSignal(text, otherClient);
}
void Client::registrationReplyReceived(QString name, QString result) {
qDebug() << "client registraion reply received";
bool reg = result == "acc" ? true : false;
if (!isRegistered)
isRegistered = reg;
clientInfo.name = name;
if (isRegistered) {
emit onRegistrationSuccessful();
} else {
emit onRegistrationFailed("registration failed, try again");
}
}
void Client::channelRequestAccepted() {
if (pendingConnections.empty()) {
qDebug() << "no pending connections";
return;
}
ClientInfo clInfo = pendingConnections.front();
pendingConnections.pop_front();
qDebug()
<< "channel request accepted by user on client for communication with: "
<< clInfo.name;
serverConnection.sendCreateChannelReply(true, clInfo.name, nextId);
expectingConnections.push_back(clInfo);
expectingIds.push_back(nextId);
++nextId;
if (!pendingConnections.empty())
emit onChannelRequestReceived(pendingConnections.front().name);
}
void Client::channelRequestDeclined() {
ClientInfo clInfo = pendingConnections.front();
pendingConnections.pop_front();
qDebug() << "channel request declined by user on client";
serverConnection.sendCreateChannelReply(false, clInfo.name, -1);
if (!pendingConnections.empty())
emit onChannelRequestReceived(pendingConnections.front().name);
}
void Client::channelActive(QString name) {
qDebug() << "CLient:: channel connected";
emit onChannelActive(name);
}
void Client::receiveCreateChannelReply(ClientInfo info, bool result, int id) {
if (!result)
return;
Channel *channel = new Channel(info, false, rsa, this);
connect(channel, SIGNAL(onMessageReceived(QString, QString)), this,
SLOT(messageReceived(QString, QString)));
connect(channel, SIGNAL(onChannelActive(QString)), this,
SLOT(channelActive(QString)));
connect(channel, SIGNAL(channelRemove(QString)), this,
SLOT(leaveChannel(QString)));
channel->connectToHost(clientPort);
channel->sendId(id);
activeChannels.push_back(channel);
}
void Client::quitPressed() {
if (isRegistered){
serverConnection.sendQuit();
for (auto ch : activeChannels){
ch->sendLeave();
}
}
emit quit();
}
void Client::leaveChannel(QString client) {
qDebug() << "leave channel";
Channel *channel = findChannel(client);
if (channel == nullptr)
return;
channel->sendLeave();
emit channelDeleted(channel->getOtherClientName());
activeChannels.removeAll(channel);
}
bool Client::initialize() {
int res = 0;
if ((res = rsa.initialize()) != 0) {
qDebug() << "could not initialize rsa client: " << res;
return false;
}
if ((res = rsa.setMyKey()) != 0) {
qDebug() << "could not generate my key client: " << res;
return false;
}
clientInfo.publicKey = rsa.getMyPublicKey();
return true;
}
Channel *Client::findChannel(QString name) {
foreach (Channel *channel, activeChannels) {
if (channel->getOtherClientName() == name) {
return channel;
}
}
return nullptr;
}
void Client::registrationSuccessful() {
emit onRegistrationSuccessful();
isRegistered = true;
}
void Client::registrationFailed() {}
void Client::updateActiveClients() {
serverConnection.sendGetActiveClientsRequest();
}
void Client::updatedActiveClients(QJsonArray clients) {
emit onActiveClientsUpdated(clients);
}