diff --git a/tools/udt-test/src/UDTTest.cpp b/tools/udt-test/src/UDTTest.cpp index 0b65907e29..4455ac586e 100644 --- a/tools/udt-test/src/UDTTest.cpp +++ b/tools/udt-test/src/UDTTest.cpp @@ -11,6 +11,8 @@ #include "UDTTest.h" +#include + #include #include @@ -29,16 +31,16 @@ const QCommandLineOption PACKET_SIZE { 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" + "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" + "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" + "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" + "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)" @@ -46,6 +48,9 @@ const QCommandLineOption UNRELIABLE_PACKETS { const QCommandLineOption ORDERED_PACKETS { "ordered", "send ordered packets (default is unordered)" }; +const QCommandLineOption MESSAGE_SIZE { + "message-size", "megabytes per message payload for ordered sending (default is 100)", "megabytes" +}; const QStringList CLIENT_STATS_TABLE_HEADERS { "Send Rate (P/s)", "Bandwidth (P/s)", "RTT(ms)", "CW (P)", "Send Period (us)", @@ -138,6 +143,17 @@ UDTTest::UDTTest(int& argc, char** argv) : _sendOrdered = true; } + if (_argumentParser.isSet(MESSAGE_SIZE)) { + if (_argumentParser.isSet(ORDERED_PACKETS)) { + static const double BYTES_PER_MEGABYTE = 1000000; + _messageSize = (int) _argumentParser.value(MESSAGE_SIZE).toInt() * BYTES_PER_MEGABYTE; + + qDebug() << "Message size for ordered packet sending is" << QString("%1MB").arg(_messageSize / BYTES_PER_MEGABYTE); + } else { + qWarning() << "message-size has no effect if not sending ordered - it will be ignored"; + } + } + if (!_target.isNull()) { sendInitialPackets(); } @@ -159,7 +175,8 @@ void UDTTest::parseArguments() { _argumentParser.addOptions({ PORT_OPTION, TARGET_OPTION, PACKET_SIZE, MIN_PACKET_SIZE, MAX_PACKET_SIZE, - MAX_SEND_BYTES, MAX_SEND_PACKETS, UNRELIABLE_PACKETS, ORDERED_PACKETS + MAX_SEND_BYTES, MAX_SEND_PACKETS, UNRELIABLE_PACKETS, ORDERED_PACKETS, + MESSAGE_SIZE }); if (!_argumentParser.parse(arguments())) { @@ -189,6 +206,8 @@ void UDTTest::sendInitialPackets() { } } +static const int FIRST_MESSAGE_SEED = 742272; + void UDTTest::sendPacket() { if (_maxSendPackets != -1 && _totalQueuedPackets > _maxSendPackets) { @@ -216,22 +235,51 @@ void UDTTest::sendPacket() { } if (_sendOrdered) { + // check if it is time to add another message - we do this every time 95% of the message size has been sent static int call = 0; - call = (call + 1) % 4; - if (call == 0) { - auto packetList = std::unique_ptr(new udt::PacketList(PacketType::BulkAvatarData, QByteArray(), true, true)); - for (int i = 0; i < 4; i++) { - packetList->writePrimitive(0x1); - packetList->writePrimitive(0x2); - packetList->writePrimitive(0x3); - packetList->writePrimitive(0x4); - packetList->closeCurrentPacket(false); + static int packetSize = udt::Packet::maxPayloadSize(true); + static int messageSizePackets = (int) ceil(_messageSize / udt::Packet::maxPayloadSize()); + + static int refillCount = (int) (messageSizePackets * 0.95); + + if (call++ % refillCount == 0) { + // construct a reliable and ordered packet list + auto packetList = std::unique_ptr({ + new udt::PacketList(PacketType::BulkAvatarData, QByteArray(), true, true) + }); + + static int currentSeed = FIRST_MESSAGE_SEED; + + std::random_device rd; + std::mt19937 generator(rd()); + + // seed the generator with a value that the receiver will also use when verifying the ordered message + generator.seed(currentSeed++); + + // setup a distribution for integer values + std::uniform_int_distribution<> dis(1, UINT64_MAX); + + // fill the packet list with random data according to the constant seed (so receiver can verify) + for (int i = 0; i < messageSizePackets; ++i) { + // setup a QByteArray full of zeros for our random padded data + QByteArray randomPaddedData { packetSize, 0 }; + + // generate a random integer for the first 8 bytes of the random data + uint64_t randomInt = dis(generator); + randomPaddedData.replace(0, sizeof(randomInt), reinterpret_cast(&randomInt)); + + // write this data to the PacketList + packetList->write(randomPaddedData); } + + packetList->closeCurrentPacket(false); + _totalQueuedBytes += packetList->getDataSize(); - + _totalQueuedPackets += packetList->getNumPackets(); + _socket.writePacketList(std::move(packetList), _target); } - _totalQueuedPackets += 4; + } else { auto newPacket = udt::Packet::create(packetPayloadSize, _sendReliable); newPacket->setPayloadSize(packetPayloadSize); @@ -239,12 +287,12 @@ void UDTTest::sendPacket() { _totalQueuedBytes += newPacket->getDataSize(); // queue or send this packet by calling write packet on the socket for our target - // if ( if (_sendReliable) { _socket.writePacket(std::move(newPacket), _target); } else { _socket.writePacket(*newPacket, _target); } + ++_totalQueuedPackets; } diff --git a/tools/udt-test/src/UDTTest.h b/tools/udt-test/src/UDTTest.h index 28aa3d340e..652a721cbc 100644 --- a/tools/udt-test/src/UDTTest.h +++ b/tools/udt-test/src/UDTTest.h @@ -48,6 +48,8 @@ private: bool _sendReliable { true }; // whether packets are sent reliably or unreliably bool _sendOrdered { false }; // whether to send ordered packets + int _messageSize { 10000000 }; // number of bytes per message while sending ordered + 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 };