-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathUDPLink.cpp
More file actions
80 lines (70 loc) · 2.8 KB
/
UDPLink.cpp
File metadata and controls
80 lines (70 loc) · 2.8 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
#include "UDPLink.h"
UDPLink::UDPLink(QObject* p) : QObject(p) {
connect(&socket_, &QUdpSocket::readyRead, this, &UDPLink::onReadyRead);
}
bool UDPLink::open(uint16_t localPort,
const QHostAddress& remoteHost,
uint16_t remotePort) {
Q_UNUSED(remoteHost);
Q_UNUSED(remotePort);
if (socket_.state() == QAbstractSocket::BoundState) {
socket_.close();
}
_hasPeer = false;
_remoteAddress = QHostAddress();
if (!socket_.bind(QHostAddress::AnyIPv4, localPort)) {
qWarning() << "Bind failed on port" << localPort << ":" << socket_.errorString();
emit linkError(QString("Bind failed: %1").arg(socket_.errorString()));
return false;
}
qInfo() << "Bound to 0.0.0.0:" << localPort
<< "(dynamic peer; waiting for first datagram)";
return true;
}
bool UDPLink::listen(uint16_t port) {
if (socket_.state() == QAbstractSocket::BoundState) socket_.close();
if (!socket_.bind(QHostAddress::AnyIPv4, port)) {
qWarning() << "Listen bind failed on port" << port << ":" << socket_.errorString();
emit linkError(QString("Bind failed: %1").arg(socket_.errorString()));
return false;
}
qInfo() << "Listening on port" << port << "(0.0.0.0:" << port << ")";
return true;
}
void UDPLink::close() { socket_.close(); }
qint64 UDPLink::writeBytes(const QByteArray& b, uint16_t remotePort) {
if (socket_.state() != QAbstractSocket::BoundState) {
qWarning() << "WriteBytes(port): socket not bound, state=" << socket_.state();
return -1;
}
if (!_hasPeer) {
qWarning() << "WriteBytes(port): no remote peer discovered yet; dropping" << b.size() << "bytes";
return -1;
}
if (_remoteAddress == QHostAddress()) {
qWarning() << "WriteBytes(port): no remote address discovered yet; dropping" << b.size() << "bytes";
return -1;
}
const qint64 n = socket_.writeDatagram(b, _remoteAddress, remotePort);
if (n == -1) {
qWarning() << "WriteDatagram failed:" << socket_.errorString()
<< "to" << _remoteAddress.toString() << ":" << remotePort;
emit linkError(socket_.errorString());
} else {
qDebug() << "Sent" << n << "bytes to" << _remoteAddress.toString() << ":" << remotePort;
}
return n;
}
void UDPLink::onReadyRead() {
readPendingDatagrams();
}
void UDPLink::readPendingDatagrams() {
while (socket_.hasPendingDatagrams()) {
QNetworkDatagram datagram = socket_.receiveDatagram();
if (!datagram.isValid()) { continue; }
const QHostAddress senderAddress = datagram.senderAddress();
if (senderAddress != _remoteAddress) { _remoteAddress = senderAddress; }
emit bytesReceived(datagram.data(), datagram.senderPort());
_hasPeer = true;
}
}