mirror of
https://github.com/overte-org/overte.git
synced 2025-08-18 15:30:45 +02:00
Merge branch 'atp' of https://github.com/birarda/hifi into protocol
This commit is contained in:
commit
d999ca833f
21 changed files with 382 additions and 70 deletions
|
@ -11,8 +11,10 @@
|
|||
|
||||
#include <QtCore/QObject>
|
||||
#include <QDebug>
|
||||
|
||||
#include <BufferParser.h>
|
||||
#include <udt/PacketHeaders.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "RegisteredMetaTypes.h"
|
||||
#include "EntityItemID.h"
|
||||
|
|
|
@ -18,11 +18,11 @@
|
|||
|
||||
#include <GLMHelpers.h>
|
||||
#include <SettingHandle.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "AddressManager.h"
|
||||
#include "NodeList.h"
|
||||
#include "NetworkLogging.h"
|
||||
#include "AddressManager.h"
|
||||
#include "UUID.h"
|
||||
|
||||
const QString ADDRESS_MANAGER_SETTINGS_GROUP = "AddressManager";
|
||||
const QString SETTINGS_CURRENT_ADDRESS_KEY = "address";
|
||||
|
|
|
@ -14,6 +14,7 @@
|
|||
|
||||
#include <QtCore/QSharedPointer>
|
||||
|
||||
#include "UUID.h"
|
||||
#include "udt/Packet.h"
|
||||
|
||||
class NLPacket : public udt::Packet {
|
||||
|
|
|
@ -16,11 +16,10 @@
|
|||
#include <QtCore/QDataStream>
|
||||
|
||||
#include <SharedUtil.h>
|
||||
#include <UUID.h>
|
||||
|
||||
#include "NetworkLogging.h"
|
||||
|
||||
#include "BandwidthRecorder.h"
|
||||
#include "NetworkLogging.h"
|
||||
#include "UUID.h"
|
||||
|
||||
NetworkPeer::NetworkPeer(QObject* parent) :
|
||||
QObject(parent),
|
||||
|
|
|
@ -12,10 +12,9 @@
|
|||
#include <cstring>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <UUID.h>
|
||||
|
||||
#include "Node.h"
|
||||
#include "SharedUtil.h"
|
||||
#include "UUID.h"
|
||||
|
||||
#include <QtCore/QDataStream>
|
||||
#include <QtCore/QDebug>
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
//
|
||||
// WalletTransaction.cpp
|
||||
// domain-server/src
|
||||
// libraries/networking/src
|
||||
//
|
||||
// Created by Stephen Birarda on 2014-05-20.
|
||||
// Copyright 2014 High Fidelity, Inc.
|
||||
|
@ -11,10 +11,10 @@
|
|||
|
||||
#include <QtCore/QJsonObject>
|
||||
|
||||
#include <UUID.h>
|
||||
|
||||
#include "UUID.h"
|
||||
#include "WalletTransaction.h"
|
||||
|
||||
|
||||
WalletTransaction::WalletTransaction() :
|
||||
_uuid(),
|
||||
_destinationUUID(),
|
||||
|
@ -64,4 +64,4 @@ void WalletTransaction::loadFromJson(const QJsonObject& jsonObject) {
|
|||
_uuid = QUuid(transactionObject.value(TRANSACTION_ID_KEY).toString());
|
||||
_destinationUUID = QUuid(transactionObject.value(TRANSACTION_DESTINATION_WALLET_ID_KEY).toString());
|
||||
_amount = transactionObject.value(TRANSACTION_AMOUNT_KEY).toInt();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -50,6 +50,8 @@ void Connection::sendReliablePacket(unique_ptr<Packet> packet) {
|
|||
if (!_sendQueue) {
|
||||
// Lasily create send queue
|
||||
_sendQueue = SendQueue::create(_parentSocket, _destination);
|
||||
|
||||
QObject::connect(_sendQueue.get(), &SendQueue::packetSent, this, &Connection::packetSent);
|
||||
}
|
||||
|
||||
_sendQueue->queuePacket(move(packet));
|
||||
|
@ -74,7 +76,7 @@ void Connection::sendACK(bool wasCausedBySyncTimeout) {
|
|||
auto currentTime = high_resolution_clock::now();
|
||||
|
||||
SequenceNumber nextACKNumber = nextACK();
|
||||
Q_ASSERT_X(nextACKNumber < _lastSentACK, "Connection::sendACK", "Sending lower ACK, something is wrong");
|
||||
Q_ASSERT_X(nextACKNumber >= _lastSentACK, "Connection::sendACK", "Sending lower ACK, something is wrong");
|
||||
|
||||
if (nextACKNumber == _lastSentACK) {
|
||||
// We already sent this ACK, but check if we should re-send it.
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
#include <QtCore/QObject>
|
||||
|
||||
#include "ConnectionStats.h"
|
||||
#include "Constants.h"
|
||||
#include "LossList.h"
|
||||
|
@ -29,8 +31,8 @@ class ControlPacket;
|
|||
class Packet;
|
||||
class Socket;
|
||||
|
||||
class Connection {
|
||||
|
||||
class Connection : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using SequenceNumberTimePair = std::pair<SequenceNumber, std::chrono::high_resolution_clock::time_point>;
|
||||
using SentACKMap = std::unordered_map<SequenceNumber, SequenceNumberTimePair>;
|
||||
|
@ -44,6 +46,9 @@ public:
|
|||
|
||||
bool processReceivedSequenceNumber(SequenceNumber sequenceNumber); // returns indicates if this packet was a duplicate
|
||||
void processControl(std::unique_ptr<ControlPacket> controlPacket);
|
||||
|
||||
signals:
|
||||
void packetSent();
|
||||
|
||||
private:
|
||||
void sendACK(bool wasCausedBySyncTimeout = true);
|
||||
|
|
|
@ -46,12 +46,12 @@ std::unique_ptr<ControlPacket> ControlPacket::create(Type type, qint64 size) {
|
|||
std::unique_ptr<ControlPacket> controlPacket;
|
||||
|
||||
if (size == -1) {
|
||||
return ControlPacket::create(type);
|
||||
return std::unique_ptr<ControlPacket>(new ControlPacket(type));
|
||||
} else {
|
||||
// Fail with invalid size
|
||||
Q_ASSERT(size >= 0);
|
||||
|
||||
return ControlPacket::create(type, size);
|
||||
return std::unique_ptr<ControlPacket>(new ControlPacket(type, size));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -21,8 +21,6 @@
|
|||
#include <QtCore/QSet>
|
||||
#include <QtCore/QUuid>
|
||||
|
||||
#include "UUID.h"
|
||||
|
||||
// If adding a new packet packetType, you can replace one marked usable or add at the end.
|
||||
// If you want the name of the packet packetType to be available for debugging or logging, update nameForPacketType() as well
|
||||
// This enum must hold 256 or fewer packet types (so the value is <= 255) since it is statically typed as a uint8_t
|
||||
|
|
|
@ -62,7 +62,9 @@ void SendQueue::run() {
|
|||
// We need to make sure this is called on the right thread
|
||||
if (thread() != QThread::currentThread()) {
|
||||
QMetaObject::invokeMethod(this, "run", Qt::QueuedConnection);
|
||||
return;
|
||||
}
|
||||
|
||||
_isRunning = true;
|
||||
|
||||
// This will loop and sleep to send packets
|
||||
|
@ -161,56 +163,64 @@ void SendQueue::loop() {
|
|||
}
|
||||
|
||||
// If there is no packet to resend, grab the next one in the list
|
||||
if (!nextPacket) {
|
||||
if (!nextPacket && _packets.size() > 0) {
|
||||
QWriteLocker locker(&_packetsLock);
|
||||
nextPacket.swap(_packets.front());
|
||||
_packets.pop_front();
|
||||
}
|
||||
|
||||
bool shouldSendSecondOfPair = false;
|
||||
|
||||
if (!hasResend) {
|
||||
// if we're not re-sending a packet then need to check if this should be a packet pair
|
||||
sequenceNumber = getNextSequenceNumber();
|
||||
if (nextPacket) {
|
||||
bool shouldSendSecondOfPair = false;
|
||||
|
||||
// the first packet in the pair is every 16 (rightmost 16 bits = 0) packets
|
||||
if (((uint32_t) sequenceNumber & 0xF) == 0) {
|
||||
shouldSendSecondOfPair = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Write packet's sequence number and send it off
|
||||
nextPacket->writeSequenceNumber(sequenceNumber);
|
||||
sendPacket(*nextPacket);
|
||||
|
||||
// Insert the packet we have just sent in the sent list
|
||||
QWriteLocker locker(&_sentLock);
|
||||
_sentPackets[nextPacket->getSequenceNumber()].swap(nextPacket);
|
||||
Q_ASSERT_X(!nextPacket,
|
||||
"SendQueue::sendNextPacket()", "Overriden packet in sent list");
|
||||
|
||||
if (shouldSendSecondOfPair) {
|
||||
std::unique_ptr<Packet> pairedPacket;
|
||||
|
||||
// we've detected we should send the second packet in a pair, do that now before sleeping
|
||||
{
|
||||
QWriteLocker locker(&_packetsLock);
|
||||
pairedPacket.swap(_packets.front());
|
||||
_packets.pop_front();
|
||||
}
|
||||
|
||||
if (pairedPacket) {
|
||||
// write this packet's sequence number and send it off
|
||||
pairedPacket->writeSequenceNumber(getNextSequenceNumber());
|
||||
sendPacket(*pairedPacket);
|
||||
if (!hasResend) {
|
||||
// if we're not re-sending a packet then need to check if this should be a packet pair
|
||||
sequenceNumber = getNextSequenceNumber();
|
||||
|
||||
// add the paired packet to the sent list
|
||||
QWriteLocker locker(&_sentLock);
|
||||
_sentPackets[pairedPacket->getSequenceNumber()].swap(pairedPacket);
|
||||
Q_ASSERT_X(!pairedPacket,
|
||||
"SendQueue::sendNextPacket()", "Overriden packet in sent list");
|
||||
// the first packet in the pair is every 16 (rightmost 16 bits = 0) packets
|
||||
if (((uint32_t) sequenceNumber & 0xF) == 0) {
|
||||
shouldSendSecondOfPair = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Write packet's sequence number and send it off
|
||||
nextPacket->writeSequenceNumber(sequenceNumber);
|
||||
sendPacket(*nextPacket);
|
||||
|
||||
// Insert the packet we have just sent in the sent list
|
||||
QWriteLocker locker(&_sentLock);
|
||||
_sentPackets[nextPacket->getSequenceNumber()].swap(nextPacket);
|
||||
Q_ASSERT_X(!nextPacket,
|
||||
"SendQueue::sendNextPacket()", "Overriden packet in sent list");
|
||||
|
||||
emit packetSent();
|
||||
|
||||
if (shouldSendSecondOfPair) {
|
||||
std::unique_ptr<Packet> pairedPacket;
|
||||
|
||||
// we've detected we should send the second packet in a pair, do that now before sleeping
|
||||
{
|
||||
QWriteLocker locker(&_packetsLock);
|
||||
pairedPacket.swap(_packets.front());
|
||||
_packets.pop_front();
|
||||
}
|
||||
|
||||
if (pairedPacket) {
|
||||
// write this packet's sequence number and send it off
|
||||
pairedPacket->writeSequenceNumber(getNextSequenceNumber());
|
||||
sendPacket(*pairedPacket);
|
||||
|
||||
// add the paired packet to the sent list
|
||||
QWriteLocker locker(&_sentLock);
|
||||
_sentPackets[pairedPacket->getSequenceNumber()].swap(pairedPacket);
|
||||
Q_ASSERT_X(!pairedPacket,
|
||||
"SendQueue::sendNextPacket()", "Overriden packet in sent list");
|
||||
|
||||
emit packetSent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
// since we're a while loop, give the thread a chance to process events
|
||||
|
|
|
@ -61,6 +61,9 @@ public slots:
|
|||
void ack(SequenceNumber ack);
|
||||
void nak(SequenceNumber start, SequenceNumber end);
|
||||
void overrideNAKListFromPacket(ControlPacket& packet);
|
||||
|
||||
signals:
|
||||
void packetSent();
|
||||
|
||||
private slots:
|
||||
void loop();
|
||||
|
|
|
@ -85,11 +85,7 @@ qint64 Socket::writePacket(const Packet& packet, const HifiSockAddr& sockAddr) {
|
|||
|
||||
qint64 Socket::writePacket(std::unique_ptr<Packet> packet, const HifiSockAddr& sockAddr) {
|
||||
if (packet->isReliable()) {
|
||||
auto it = _connectionsHash.find(sockAddr);
|
||||
if (it == _connectionsHash.end()) {
|
||||
it = _connectionsHash.insert(it, std::make_pair(sockAddr, new Connection(this, sockAddr, _ccFactory->create())));
|
||||
}
|
||||
it->second->sendReliablePacket(std::move(packet));
|
||||
findOrCreateConnection(sockAddr)->sendReliablePacket(move(packet));
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -111,6 +107,16 @@ qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& soc
|
|||
return bytesWritten;
|
||||
}
|
||||
|
||||
Connection* Socket::findOrCreateConnection(const HifiSockAddr& sockAddr) {
|
||||
auto it = _connectionsHash.find(sockAddr);
|
||||
|
||||
if (it == _connectionsHash.end()) {
|
||||
it = _connectionsHash.insert(it, std::make_pair(sockAddr, new Connection(this, sockAddr, _ccFactory->create())));
|
||||
}
|
||||
|
||||
return it->second;
|
||||
}
|
||||
|
||||
void Socket::readPendingDatagrams() {
|
||||
while (_udpSocket.hasPendingDatagrams()) {
|
||||
// setup a HifiSockAddr to read into
|
||||
|
@ -144,11 +150,8 @@ void Socket::readPendingDatagrams() {
|
|||
auto controlPacket = ControlPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr);
|
||||
|
||||
// move this control packet to the matching connection
|
||||
auto it = _connectionsHash.find(senderSockAddr);
|
||||
|
||||
if (it != _connectionsHash.end()) {
|
||||
it->second->processControl(move(controlPacket));
|
||||
}
|
||||
auto connection = findOrCreateConnection(senderSockAddr);
|
||||
connection->processControl(move(controlPacket));
|
||||
|
||||
} else {
|
||||
// setup a Packet from the data we just read
|
||||
|
@ -176,6 +179,13 @@ void Socket::readPendingDatagrams() {
|
|||
}
|
||||
}
|
||||
|
||||
void Socket::connectToSendSignal(const HifiSockAddr& destinationAddr, QObject* receiver, const char* slot) {
|
||||
auto it = _connectionsHash.find(destinationAddr);
|
||||
if (it != _connectionsHash.end()) {
|
||||
connect(it->second, SIGNAL(packetSent()), receiver, slot);
|
||||
}
|
||||
}
|
||||
|
||||
void Socket::rateControlSync() {
|
||||
|
||||
// enumerate our list of connections and ask each of them to send off periodic ACK packet for rate control
|
||||
|
|
|
@ -60,6 +60,8 @@ public:
|
|||
{ _unfilteredHandlers[senderSockAddr] = handler; }
|
||||
|
||||
void setCongestionControlFactory(std::unique_ptr<CongestionControlVirtualFactory> ccFactory);
|
||||
|
||||
void connectToSendSignal(const HifiSockAddr& destinationAddr, QObject* receiver, const char* slot);
|
||||
|
||||
private slots:
|
||||
void readPendingDatagrams();
|
||||
|
@ -67,6 +69,7 @@ private slots:
|
|||
|
||||
private:
|
||||
void setSystemBufferSizes();
|
||||
Connection* findOrCreateConnection(const HifiSockAddr& sockAddr);
|
||||
|
||||
QUdpSocket _udpSocket { this };
|
||||
PacketFilterOperator _packetFilterOperator;
|
||||
|
|
|
@ -5,6 +5,8 @@ set_target_properties(mtc PROPERTIES FOLDER "Tools")
|
|||
add_subdirectory(scribe)
|
||||
set_target_properties(scribe PROPERTIES FOLDER "Tools")
|
||||
|
||||
add_subdirectory(udt-test)
|
||||
set_target_properties(udt-test PROPERTIES FOLDER "Tools")
|
||||
|
||||
add_subdirectory(vhacd-util)
|
||||
set_target_properties(vhacd-util PROPERTIES FOLDER "Tools")
|
||||
|
||||
|
|
6
tools/udt-test/CMakeLists.txt
Normal file
6
tools/udt-test/CMakeLists.txt
Normal file
|
@ -0,0 +1,6 @@
|
|||
set(TARGET_NAME udt-test)
|
||||
setup_hifi_project()
|
||||
|
||||
link_hifi_libraries(networking)
|
||||
|
||||
copy_dlls_beside_windows_executable()
|
200
tools/udt-test/src/UDTTest.cpp
Normal file
200
tools/udt-test/src/UDTTest.cpp
Normal file
|
@ -0,0 +1,200 @@
|
|||
//
|
||||
// UDTTest.cpp
|
||||
// tools/udt-test/src
|
||||
//
|
||||
// Created by Stephen Birarda on 2015-07-30.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#include "UDTTest.h"
|
||||
|
||||
#include <QtCore/QDebug>
|
||||
|
||||
#include <udt/Constants.h>
|
||||
#include <udt/Packet.h>
|
||||
|
||||
const QCommandLineOption PORT_OPTION { "p", "listening port for socket (defaults to random)", "port", 0 };
|
||||
const QCommandLineOption TARGET_OPTION {
|
||||
"target", "target for sent packets (default is listen only)",
|
||||
"IP:PORT or HOSTNAME:PORT"
|
||||
};
|
||||
const QCommandLineOption PACKET_SIZE {
|
||||
"packet-size", "size for sent packets in bytes (defaults to 1500)", "bytes",
|
||||
QString(udt::MAX_PACKET_SIZE_WITH_UDP_HEADER)
|
||||
};
|
||||
const QCommandLineOption MIN_PACKET_SIZE {
|
||||
"min-packet-size", "min size for sent packets in bytes", "min-bytes"
|
||||
};
|
||||
const QCommandLineOption MAX_PACKET_SIZE {
|
||||
"max-packet-size", "max size for sent packets in bytes", "max-bytes"
|
||||
};
|
||||
const QCommandLineOption MAX_SEND_BYTES {
|
||||
"max-send-bytes", "number of bytes to send before stopping (default is infinite)", "max-bytes"
|
||||
};
|
||||
const QCommandLineOption MAX_SEND_PACKETS {
|
||||
"max-send-packets", "number of packets to send before stopping (default is infinite)", "max-packets"
|
||||
};
|
||||
const QCommandLineOption UNRELIABLE_PACKETS {
|
||||
"unreliable", "send unreliable packets (default is reliable)"
|
||||
};
|
||||
|
||||
UDTTest::UDTTest(int& argc, char** argv) :
|
||||
QCoreApplication(argc, argv)
|
||||
{
|
||||
parseArguments();
|
||||
|
||||
// randomize the seed for packet size randomization
|
||||
srand(time(NULL));
|
||||
|
||||
_socket.bind(QHostAddress::LocalHost, _argumentParser.value(PORT_OPTION).toUInt());
|
||||
qDebug() << "Test socket is listening on" << _socket.localPort();
|
||||
|
||||
if (_argumentParser.isSet(TARGET_OPTION)) {
|
||||
// parse the IP and port combination for this target
|
||||
QString hostnamePortString = _argumentParser.value(TARGET_OPTION);
|
||||
|
||||
QHostAddress address { hostnamePortString.left(hostnamePortString.indexOf(':')) };
|
||||
quint16 port { (quint16) hostnamePortString.mid(hostnamePortString.indexOf(':') + 1).toUInt() };
|
||||
|
||||
if (address.isNull() || port == 0) {
|
||||
qCritical() << "Could not parse an IP address and port combination from" << hostnamePortString << "-" <<
|
||||
"The parsed IP was" << address.toString() << "and the parsed port was" << port;
|
||||
|
||||
QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
|
||||
} else {
|
||||
_target = HifiSockAddr(address, port);
|
||||
}
|
||||
}
|
||||
|
||||
if (_argumentParser.isSet(PACKET_SIZE)) {
|
||||
// parse the desired packet size
|
||||
_minPacketSize = _maxPacketSize = _argumentParser.value(PACKET_SIZE).toInt();
|
||||
|
||||
if (_argumentParser.isSet(MIN_PACKET_SIZE) || _argumentParser.isSet(MAX_PACKET_SIZE)) {
|
||||
qCritical() << "Cannot set a min packet size or max packet size AND a specific packet size.";
|
||||
QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
|
||||
}
|
||||
} else {
|
||||
|
||||
bool customMinSize = false;
|
||||
|
||||
if (_argumentParser.isSet(MIN_PACKET_SIZE)) {
|
||||
_minPacketSize = _argumentParser.value(MIN_PACKET_SIZE).toInt();
|
||||
customMinSize = true;
|
||||
}
|
||||
|
||||
if (_argumentParser.isSet(MAX_PACKET_SIZE)) {
|
||||
_maxPacketSize = _argumentParser.value(MAX_PACKET_SIZE).toInt();
|
||||
|
||||
// if we don't have a min packet size we should make it 1, because we have a max
|
||||
if (customMinSize) {
|
||||
_minPacketSize = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (_maxPacketSize < _minPacketSize) {
|
||||
qCritical() << "Cannot set a max packet size that is smaller than the min packet size.";
|
||||
QMetaObject::invokeMethod(this, "quit", Qt::QueuedConnection);
|
||||
}
|
||||
}
|
||||
|
||||
if (_argumentParser.isSet(MAX_SEND_BYTES)) {
|
||||
_maxSendBytes = _argumentParser.value(MAX_SEND_BYTES).toInt();
|
||||
}
|
||||
|
||||
if (_argumentParser.isSet(MAX_SEND_PACKETS)) {
|
||||
_maxSendPackets = _argumentParser.value(MAX_SEND_PACKETS).toInt();
|
||||
}
|
||||
|
||||
if (_argumentParser.isSet(UNRELIABLE_PACKETS)) {
|
||||
_sendReliable = false;
|
||||
}
|
||||
|
||||
if (!_target.isNull()) {
|
||||
sendInitialPackets();
|
||||
}
|
||||
}
|
||||
|
||||
void UDTTest::parseArguments() {
|
||||
// use a QCommandLineParser to setup command line arguments and give helpful output
|
||||
_argumentParser.setApplicationDescription("High Fidelity UDT Protocol Test Client");
|
||||
_argumentParser.addHelpOption();
|
||||
|
||||
const QCommandLineOption helpOption = _argumentParser.addHelpOption();
|
||||
|
||||
_argumentParser.addOptions({
|
||||
PORT_OPTION, TARGET_OPTION, PACKET_SIZE, MIN_PACKET_SIZE, MAX_PACKET_SIZE,
|
||||
MAX_SEND_BYTES, MAX_SEND_PACKETS, UNRELIABLE_PACKETS
|
||||
});
|
||||
|
||||
if (!_argumentParser.parse(arguments())) {
|
||||
qCritical() << _argumentParser.errorText();
|
||||
_argumentParser.showHelp();
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
|
||||
if (_argumentParser.isSet(helpOption)) {
|
||||
_argumentParser.showHelp();
|
||||
Q_UNREACHABLE();
|
||||
}
|
||||
}
|
||||
|
||||
void UDTTest::sendInitialPackets() {
|
||||
static const int NUM_INITIAL_PACKETS = 10;
|
||||
|
||||
int numPackets = std::max(NUM_INITIAL_PACKETS, _maxSendPackets);
|
||||
|
||||
for (int i = 0; i < numPackets; ++i) {
|
||||
sendPacket();
|
||||
}
|
||||
|
||||
if (numPackets == NUM_INITIAL_PACKETS) {
|
||||
// we've put 500 initial packets in the queue, everytime we hear one has gone out we should add a new one
|
||||
_socket.connectToSendSignal(_target, this, SLOT(refillPacket()));
|
||||
}
|
||||
}
|
||||
|
||||
void UDTTest::sendPacket() {
|
||||
|
||||
qDebug() << "Sending packet" << _totalQueuedPackets + 1;
|
||||
|
||||
if (_maxSendPackets != -1 && _totalQueuedPackets > _maxSendPackets) {
|
||||
// don't send more packets, we've hit max
|
||||
return;
|
||||
}
|
||||
|
||||
if (_maxSendBytes != -1 && _totalQueuedBytes > _maxSendBytes) {
|
||||
// don't send more packets, we've hit max
|
||||
return;
|
||||
}
|
||||
|
||||
// we're good to send a new packet, construct it now
|
||||
|
||||
// figure out what size the packet will be
|
||||
int packetPayloadSize = 0;
|
||||
|
||||
if (_minPacketSize == _maxPacketSize) {
|
||||
// we know what size we want - figure out the payload size
|
||||
packetPayloadSize = _maxPacketSize - udt::Packet::localHeaderSize(false);
|
||||
} else {
|
||||
// pick a random size in our range
|
||||
int randomPacketSize = rand() % _maxPacketSize + _minPacketSize;
|
||||
packetPayloadSize = randomPacketSize - udt::Packet::localHeaderSize(false);
|
||||
}
|
||||
|
||||
auto newPacket = udt::Packet::create(packetPayloadSize, _sendReliable);
|
||||
|
||||
_totalQueuedBytes += newPacket->getDataSize();
|
||||
|
||||
// queue or send this packet by calling write packet on the socket for our target
|
||||
if (_sendReliable) {
|
||||
_socket.writePacket(std::move(newPacket), _target);
|
||||
} else {
|
||||
_socket.writePacket(*newPacket, _target);
|
||||
}
|
||||
|
||||
++_totalQueuedPackets;
|
||||
}
|
53
tools/udt-test/src/UDTTest.h
Normal file
53
tools/udt-test/src/UDTTest.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
//
|
||||
// UDTTest.h
|
||||
// tools/udt-test/src
|
||||
//
|
||||
// Created by Stephen Birarda on 2015-07-30.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#ifndef hifi_UDTTest_h
|
||||
#define hifi_UDTTest_h
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QCommandLineParser>
|
||||
|
||||
#include <udt/Constants.h>
|
||||
#include <udt/Socket.h>
|
||||
|
||||
class UDTTest : public QCoreApplication {
|
||||
Q_OBJECT
|
||||
public:
|
||||
UDTTest(int& argc, char** argv);
|
||||
|
||||
public slots:
|
||||
void refillPacket() { sendPacket(); } // adds a new packet to the queue when we are told one is sent
|
||||
|
||||
private:
|
||||
void parseArguments();
|
||||
|
||||
void sendInitialPackets(); // fills the queue with packets to start
|
||||
void sendPacket(); // constructs and sends a packet according to the test parameters
|
||||
|
||||
QCommandLineParser _argumentParser;
|
||||
udt::Socket _socket;
|
||||
|
||||
HifiSockAddr _target; // the target for sent packets
|
||||
|
||||
int _minPacketSize { udt::MAX_PACKET_SIZE };
|
||||
int _maxPacketSize { udt::MAX_PACKET_SIZE };
|
||||
int _maxSendBytes { -1 }; // the number of bytes to send to the target before stopping
|
||||
int _maxSendPackets { -1 }; // the number of packets to send to the target before stopping
|
||||
|
||||
bool _sendReliable { true }; // wether packets are sent reliably or unreliably
|
||||
|
||||
int _totalQueuedPackets { 0 }; // keeps track of the number of packets we have already queued
|
||||
int _totalQueuedBytes { 0 }; // keeps track of the number of bytes we have already queued
|
||||
};
|
||||
|
||||
#endif // hifi_UDTTest_h
|
19
tools/udt-test/src/main.cpp
Normal file
19
tools/udt-test/src/main.cpp
Normal file
|
@ -0,0 +1,19 @@
|
|||
//
|
||||
// main.cpp
|
||||
// tools/udt-test/src
|
||||
//
|
||||
// Created by Stephen Birarda on 7/30/15.
|
||||
// Copyright 2015 High Fidelity, Inc.
|
||||
//
|
||||
// Distributed under the Apache License, Version 2.0.
|
||||
// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
|
||||
#include "UDTTest.h"
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
UDTTest app(argc, argv);
|
||||
return app.exec();
|
||||
}
|
||||
|
Loading…
Reference in a new issue