From 9556fecbe2de298969769b005623cd19a513434c Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Mon, 20 Jul 2015 17:10:22 -0700 Subject: [PATCH] initial changes to make _nodeSocket a udt::Socket --- assignment-client/src/audio/AudioMixer.cpp | 3 - domain-server/src/DomainServer.cpp | 2 +- libraries/networking/src/LimitedNodeList.cpp | 55 +--- libraries/networking/src/LimitedNodeList.h | 12 +- libraries/networking/src/NLPacket.cpp | 49 +++- libraries/networking/src/NLPacket.h | 11 +- libraries/networking/src/PacketReceiver.cpp | 265 +++++++++---------- libraries/networking/src/PacketReceiver.h | 5 +- libraries/networking/src/udt/Packet.cpp | 18 +- libraries/networking/src/udt/Socket.cpp | 68 +++++ libraries/networking/src/udt/Socket.h | 55 ++++ 11 files changed, 333 insertions(+), 210 deletions(-) create mode 100644 libraries/networking/src/udt/Socket.cpp create mode 100644 libraries/networking/src/udt/Socket.h diff --git a/assignment-client/src/audio/AudioMixer.cpp b/assignment-client/src/audio/AudioMixer.cpp index b68332210b..aa8e405d34 100644 --- a/assignment-client/src/audio/AudioMixer.cpp +++ b/assignment-client/src/audio/AudioMixer.cpp @@ -652,9 +652,6 @@ void AudioMixer::run() { auto nodeList = DependencyManager::get(); - // we do not want this event loop to be the handler for UDP datagrams, so disconnect - disconnect(&nodeList->getNodeSocket(), 0, this, 0); - nodeList->addNodeTypeToInterestSet(NodeType::Agent); nodeList->linkedDataCreateCallback = [](Node* node) { diff --git a/domain-server/src/DomainServer.cpp b/domain-server/src/DomainServer.cpp index c13de0449e..4532180ca7 100644 --- a/domain-server/src/DomainServer.cpp +++ b/domain-server/src/DomainServer.cpp @@ -259,7 +259,7 @@ void DomainServer::setupNodeListAndAssignments(const QUuid& sessionUUID) { auto nodeList = DependencyManager::set(domainServerPort, domainServerDTLSPort); // no matter the local port, save it to shared mem so that local assignment clients can ask what it is - nodeList->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this, nodeList->getNodeSocket().localPort()); + nodeList->putLocalPortIntoSharedMemory(DOMAIN_SERVER_LOCAL_PORT_SMEM_KEY, this, nodeList->getSocketLocalPort()); // store our local http ports in shared memory quint16 localHttpPort = DOMAIN_SERVER_HTTP_PORT; diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index fdb3461c1f..c36931fa9e 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -82,7 +82,7 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short } const int LARGER_BUFFER_SIZE = 1048576; - changeSocketBufferSizes(LARGER_BUFFER_SIZE); + _nodeSocket.setBufferSizes(LARGER_BUFFER_SIZE); // check for local socket updates every so often const int LOCAL_SOCKET_UPDATE_INTERVAL_MSECS = 5 * 1000; @@ -96,10 +96,10 @@ LimitedNodeList::LimitedNodeList(unsigned short socketListenPort, unsigned short // check the local socket right now updateLocalSockAddr(); - - // TODO: Create a new thread, and move PacketReceiver to it - - connect(&_nodeSocket, &QUdpSocket::readyRead, _packetReceiver, &PacketReceiver::processDatagrams); + + // set &PacketReceiver::handleVerifiedPacket as the verified packet function for the udt::Socket + using std::placeholders::_1; + _nodeSocket.setVerifiedPacketFunction(std::bind(&PacketReceiver::handleVerifiedPacket, _packetReceiver, _1)); _packetStatTimer.start(); @@ -149,32 +149,6 @@ QUdpSocket& LimitedNodeList::getDTLSSocket() { return *_dtlsSocket; } -void LimitedNodeList::changeSocketBufferSizes(int numBytes) { - for (int i = 0; i < 2; i++) { - QAbstractSocket::SocketOption bufferOpt; - QString bufferTypeString; - if (i == 0) { - bufferOpt = QAbstractSocket::SendBufferSizeSocketOption; - bufferTypeString = "send"; - - } else { - bufferOpt = QAbstractSocket::ReceiveBufferSizeSocketOption; - bufferTypeString = "receive"; - } - int oldBufferSize = _nodeSocket.socketOption(bufferOpt).toInt(); - if (oldBufferSize < numBytes) { - int newBufferSize = _nodeSocket.socketOption(bufferOpt).toInt(); - - qCDebug(networking) << "Changed socket" << bufferTypeString << "buffer size from" << oldBufferSize << "to" - << newBufferSize << "bytes"; - } else { - // don't make the buffer smaller - qCDebug(networking) << "Did not change socket" << bufferTypeString << "buffer size from" << oldBufferSize - << "since it is larger than desired size of" << numBytes; - } - } -} - bool LimitedNodeList::packetSourceAndHashMatch(const NLPacket& packet, SharedNodePointer& matchingNode) { if (NON_SOURCED_PACKETS.contains(packet.getType())) { @@ -255,12 +229,7 @@ qint64 LimitedNodeList::writeDatagram(const QByteArray& datagram, const HifiSock ++_numCollectedPackets; _numCollectedBytes += datagram.size(); - qint64 bytesWritten = _nodeSocket.writeDatagram(datagram, - destinationSockAddr.getAddress(), destinationSockAddr.getPort()); - - if (bytesWritten < 0) { - qCDebug(networking) << "ERROR in writeDatagram:" << _nodeSocket.error() << "-" << _nodeSocket.errorString(); - } + qint64 bytesWritten = _nodeSocket.writeDatagram(datagram, destinationSockAddr); return bytesWritten; } @@ -571,7 +540,7 @@ void LimitedNodeList::sendSTUNRequest() { ++_numInitialSTUNRequests; } - unsigned char stunRequestPacket[NUM_BYTES_STUN_HEADER]; + char stunRequestPacket[NUM_BYTES_STUN_HEADER]; int packetIndex = 0; @@ -597,15 +566,7 @@ void LimitedNodeList::sendSTUNRequest() { flagTimeForConnectionStep(ConnectionStep::SendSTUNRequest); - _nodeSocket.writeDatagram((char*) stunRequestPacket, sizeof(stunRequestPacket), - _stunSockAddr.getAddress(), _stunSockAddr.getPort()); -} - -void LimitedNodeList::rebindNodeSocket() { - quint16 oldPort = _nodeSocket.localPort(); - - _nodeSocket.close(); - _nodeSocket.bind(QHostAddress::AnyIPv4, oldPort); + _nodeSocket.writeDatagram(stunRequestPacket, _stunSockAddr); } bool LimitedNodeList::processSTUNResponse(QSharedPointer packet) { diff --git a/libraries/networking/src/LimitedNodeList.h b/libraries/networking/src/LimitedNodeList.h index 33d490c960..8a4230be04 100644 --- a/libraries/networking/src/LimitedNodeList.h +++ b/libraries/networking/src/LimitedNodeList.h @@ -37,9 +37,10 @@ #include "DomainHandler.h" #include "Node.h" #include "NLPacket.h" -#include "udt/PacketHeaders.h" #include "PacketReceiver.h" #include "NLPacketList.h" +#include "udt/PacketHeaders.h" +#include "udt/Socket.h" #include "UUIDHasher.h" const quint64 NODE_SILENCE_THRESHOLD_MSECS = 2 * 1000; @@ -109,9 +110,8 @@ public: bool getThisNodeCanRez() const { return _thisNodeCanRez; } void setThisNodeCanRez(bool canRez); - - void rebindNodeSocket(); - QUdpSocket& getNodeSocket() { return _nodeSocket; } + + quint16 getSocketLocalPort() const { return _nodeSocket.localPort(); } QUdpSocket& getDTLSSocket(); bool packetSourceAndHashMatch(const NLPacket& packet, SharedNodePointer& matchingNode); @@ -256,8 +256,6 @@ protected: PacketSequenceNumber getNextSequenceNumberForPacket(const QUuid& nodeUUID, PacketType::Value packetType); - void changeSocketBufferSizes(int numBytes); - void handleNodeKill(const SharedNodePointer& node); void stopInitialSTUNUpdate(bool success); @@ -272,7 +270,7 @@ protected: QUuid _sessionUUID; NodeHash _nodeHash; QReadWriteLock _nodeMutex; - QUdpSocket _nodeSocket; + udt::Socket _nodeSocket; QUdpSocket* _dtlsSocket; HifiSockAddr _localSockAddr; HifiSockAddr _publicSockAddr; diff --git a/libraries/networking/src/NLPacket.cpp b/libraries/networking/src/NLPacket.cpp index 7a6503dbc3..7ccd33a1ed 100644 --- a/libraries/networking/src/NLPacket.cpp +++ b/libraries/networking/src/NLPacket.cpp @@ -63,6 +63,14 @@ std::unique_ptr NLPacket::fromReceivedPacket(std::unique_ptr dat } +std::unique_ptr NLPacket::fromBase(std::unique_ptr packet) { + // Fail with null packet + Q_ASSERT(packet); + + // call our constructor to create an NLPacket from this Packet + return std::unique_ptr(new NLPacket(std::move(packet))); +} + std::unique_ptr NLPacket::createCopy(const NLPacket& other) { return std::unique_ptr(new NLPacket(other)); } @@ -81,24 +89,59 @@ NLPacket::NLPacket(PacketType::Value type) : adjustPayloadStartAndCapacity(); } -NLPacket::NLPacket(const NLPacket& other) : Packet(other) { +NLPacket::NLPacket(std::unique_ptr packet) : + Packet(*packet) +{ + adjustPayloadStartAndCapacity(_payloadSize > 0); + readSourceID(); + readVerificationHash(); +} + +NLPacket::NLPacket(const NLPacket& other) : Packet(other) { + *this = other; +} + +NLPacket& NLPacket::operator=(const NLPacket& other) { + Packet::operator=(other); + + _sourceID = other._sourceID; + _verificationHash = other._verificationHash; + + return *this; } NLPacket::NLPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr) : Packet(std::move(data), size, senderSockAddr) { adjustPayloadStartAndCapacity(); - _payloadSize = _payloadCapacity; readSourceID(); readVerificationHash(); } -void NLPacket::adjustPayloadStartAndCapacity() { +NLPacket::NLPacket(NLPacket&& other) : + Packet(other) +{ + *this = std::move(other); +} + +NLPacket& NLPacket::operator=(NLPacket&& other) { + _sourceID = std::move(other._sourceID); + _verificationHash = std::move(other._verificationHash); + + return *this; +} + + +void NLPacket::adjustPayloadStartAndCapacity(bool shouldDecreasePayloadSize) { qint64 headerSize = localHeaderSize(_type); _payloadStart += headerSize; _payloadCapacity -= headerSize; + + if (shouldDecreasePayloadSize) { + _payloadSize -= headerSize; + } } void NLPacket::readSourceID() { diff --git a/libraries/networking/src/NLPacket.h b/libraries/networking/src/NLPacket.h index 669278ed65..eab0fa3a99 100644 --- a/libraries/networking/src/NLPacket.h +++ b/libraries/networking/src/NLPacket.h @@ -22,6 +22,8 @@ public: static std::unique_ptr create(PacketType::Value type, qint64 size = -1); static std::unique_ptr fromReceivedPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); + static std::unique_ptr fromBase(std::unique_ptr packet); + // Provided for convenience, try to limit use static std::unique_ptr createCopy(const NLPacket& other); @@ -41,12 +43,19 @@ public: protected: - void adjustPayloadStartAndCapacity(); + void adjustPayloadStartAndCapacity(bool shouldDecreasePayloadSize = false); NLPacket(PacketType::Value type); NLPacket(PacketType::Value type, qint64 size); + NLPacket(std::unique_ptr data, qint64 size, const HifiSockAddr& senderSockAddr); + NLPacket(std::unique_ptr packet); + NLPacket(const NLPacket& other); + NLPacket& operator=(const NLPacket& other); + + NLPacket(NLPacket&& other); + NLPacket& operator=(NLPacket&& other); void readSourceID(); void readVerificationHash(); diff --git a/libraries/networking/src/PacketReceiver.cpp b/libraries/networking/src/PacketReceiver.cpp index f59be35dc5..a97b212355 100644 --- a/libraries/networking/src/PacketReceiver.cpp +++ b/libraries/networking/src/PacketReceiver.cpp @@ -234,147 +234,134 @@ bool PacketReceiver::packetVersionMatch(const NLPacket& packet) { } } -void PacketReceiver::processDatagrams() { - //PerformanceWarning warn(Menu::getInstance()->isOptionChecked(MenuOption::PipelineWarnings), - //"PacketReceiver::processDatagrams()"); - +void PacketReceiver::handleVerifiedPacket(std::unique_ptr packet) { + + // if we're supposed to drop this packet then break out here + if (_shouldDropPackets) { + return; + } + auto nodeList = DependencyManager::get(); - - while (nodeList && nodeList->getNodeSocket().hasPendingDatagrams()) { - // setup a buffer to read the packet into - int packetSizeWithHeader = nodeList->getNodeSocket().pendingDatagramSize(); - std::unique_ptr buffer = std::unique_ptr(new char[packetSizeWithHeader]); - - // if we're supposed to drop this packet then break out here - if (_shouldDropPackets) { - break; - } - - // setup a HifiSockAddr to read into - HifiSockAddr senderSockAddr; - - // pull the datagram - nodeList->getNodeSocket().readDatagram(buffer.get(), packetSizeWithHeader, - senderSockAddr.getAddressPointer(), senderSockAddr.getPortPointer()); - - // setup an NLPacket from the data we just read - auto packet = NLPacket::fromReceivedPacket(std::move(buffer), packetSizeWithHeader, senderSockAddr); + + // setup a HifiSockAddr to read into + HifiSockAddr senderSockAddr; + + // setup an NLPacket from the data we just read + auto nlPacket = NLPacket::fromBase(std::move(packet)); + + _inPacketCount++; + _inByteCount += nlPacket->getDataSize(); + + SharedNodePointer matchingNode; + if (!nlPacket->getSourceID().isNull()) { + matchingNode = nodeList->nodeWithUUID(nlPacket->getSourceID()); - _inPacketCount++; - _inByteCount += packetSizeWithHeader; - - if (packetVersionMatch(*packet)) { - - SharedNodePointer matchingNode; - if (nodeList->packetSourceAndHashMatch(*packet, matchingNode)) { - - if (matchingNode) { - // No matter if this packet is handled or not, we update the timestamp for the last time we heard - // from this sending node - matchingNode->setLastHeardMicrostamp(usecTimestampNow()); - } - - _packetListenerLock.lock(); - - bool listenerIsDead = false; - - auto it = _packetListenerMap.find(packet->getType()); - - if (it != _packetListenerMap.end()) { - - auto listener = it.value(); - - if (listener.first) { - - bool success = false; - - // check if this is a directly connected listener - _directConnectSetMutex.lock(); - - Qt::ConnectionType connectionType = - _directlyConnectedObjects.contains(listener.first) ? Qt::DirectConnection : Qt::AutoConnection; - - _directConnectSetMutex.unlock(); - - PacketType::Value packetType = packet->getType(); - - if (matchingNode) { - // if this was a sequence numbered packet we should store the last seq number for - // a packet of this type for this node - if (SEQUENCE_NUMBERED_PACKETS.contains(packet->getType())) { - matchingNode->setLastSequenceNumberForPacketType(packet->readSequenceNumber(), packet->getType()); - } - - emit dataReceived(matchingNode->getType(), packet->getDataSize()); - QMetaMethod metaMethod = listener.second; - - static const QByteArray QSHAREDPOINTER_NODE_NORMALIZED = QMetaObject::normalizedType("QSharedPointer"); - static const QByteArray SHARED_NODE_NORMALIZED = QMetaObject::normalizedType("SharedNodePointer"); - - // one final check on the QPointer before we go to invoke - if (listener.first) { - if (metaMethod.parameterTypes().contains(SHARED_NODE_NORMALIZED)) { - success = metaMethod.invoke(listener.first, - connectionType, - Q_ARG(QSharedPointer, - QSharedPointer(packet.release())), - Q_ARG(SharedNodePointer, matchingNode)); - - } else if (metaMethod.parameterTypes().contains(QSHAREDPOINTER_NODE_NORMALIZED)) { - success = metaMethod.invoke(listener.first, - connectionType, - Q_ARG(QSharedPointer, - QSharedPointer(packet.release())), - Q_ARG(QSharedPointer, matchingNode)); - - } else { - success = metaMethod.invoke(listener.first, - connectionType, - Q_ARG(QSharedPointer, - QSharedPointer(packet.release()))); - } - } else { - listenerIsDead = true; - } - - } else { - emit dataReceived(NodeType::Unassigned, packet->getDataSize()); - - success = listener.second.invoke(listener.first, - Q_ARG(QSharedPointer, QSharedPointer(packet.release()))); - } - - if (!success) { - qDebug().nospace() << "Error delivering packet " << packetType - << " (" << qPrintable(nameForPacketType(packetType)) << ") to listener " - << listener.first << "::" << qPrintable(listener.second.methodSignature()); - } - - } else { - listenerIsDead = true; - } - - if (listenerIsDead) { - qDebug().nospace() << "Listener for packet" << packet->getType() - << " (" << qPrintable(nameForPacketType(packet->getType())) << ")" - << " has been destroyed. Removing from listener map."; - it = _packetListenerMap.erase(it); - - // if it exists, remove the listener from _directlyConnectedObjects - _directConnectSetMutex.lock(); - _directlyConnectedObjects.remove(listener.first); - _directConnectSetMutex.unlock(); - } - - } else { - qWarning() << "No listener found for packet type " << nameForPacketType(packet->getType()); - - // insert a dummy listener so we don't print this again - _packetListenerMap.insert(packet->getType(), { nullptr, QMetaMethod() }); - } - - _packetListenerLock.unlock(); - } + if (matchingNode) { + // No matter if this packet is handled or not, we update the timestamp for the last time we heard + // from this sending node + matchingNode->setLastHeardMicrostamp(usecTimestampNow()); } } + + _packetListenerLock.lock(); + + bool listenerIsDead = false; + + auto it = _packetListenerMap.find(packet->getType()); + + if (it != _packetListenerMap.end()) { + + auto listener = it.value(); + + if (listener.first) { + + bool success = false; + + // check if this is a directly connected listener + _directConnectSetMutex.lock(); + + Qt::ConnectionType connectionType = + _directlyConnectedObjects.contains(listener.first) ? Qt::DirectConnection : Qt::AutoConnection; + + _directConnectSetMutex.unlock(); + + PacketType::Value packetType = packet->getType(); + + if (matchingNode) { + // if this was a sequence numbered packet we should store the last seq number for + // a packet of this type for this node + if (SEQUENCE_NUMBERED_PACKETS.contains(packet->getType())) { + matchingNode->setLastSequenceNumberForPacketType(packet->readSequenceNumber(), packet->getType()); + } + + emit dataReceived(matchingNode->getType(), packet->getDataSize()); + QMetaMethod metaMethod = listener.second; + + static const QByteArray QSHAREDPOINTER_NODE_NORMALIZED = QMetaObject::normalizedType("QSharedPointer"); + static const QByteArray SHARED_NODE_NORMALIZED = QMetaObject::normalizedType("SharedNodePointer"); + + // one final check on the QPointer before we go to invoke + if (listener.first) { + if (metaMethod.parameterTypes().contains(SHARED_NODE_NORMALIZED)) { + success = metaMethod.invoke(listener.first, + connectionType, + Q_ARG(QSharedPointer, + QSharedPointer(nlPacket.release())), + Q_ARG(SharedNodePointer, matchingNode)); + + } else if (metaMethod.parameterTypes().contains(QSHAREDPOINTER_NODE_NORMALIZED)) { + success = metaMethod.invoke(listener.first, + connectionType, + Q_ARG(QSharedPointer, + QSharedPointer(nlPacket.release())), + Q_ARG(QSharedPointer, matchingNode)); + + } else { + success = metaMethod.invoke(listener.first, + connectionType, + Q_ARG(QSharedPointer, + QSharedPointer(nlPacket.release()))); + } + } else { + listenerIsDead = true; + } + + } else { + emit dataReceived(NodeType::Unassigned, packet->getDataSize()); + + success = listener.second.invoke(listener.first, + Q_ARG(QSharedPointer, QSharedPointer(nlPacket.release()))); + } + + if (!success) { + qDebug().nospace() << "Error delivering packet " << packetType + << " (" << qPrintable(nameForPacketType(packetType)) << ") to listener " + << listener.first << "::" << qPrintable(listener.second.methodSignature()); + } + + } else { + listenerIsDead = true; + } + + if (listenerIsDead) { + qDebug().nospace() << "Listener for packet" << packet->getType() + << " (" << qPrintable(nameForPacketType(packet->getType())) << ")" + << " has been destroyed. Removing from listener map."; + it = _packetListenerMap.erase(it); + + // if it exists, remove the listener from _directlyConnectedObjects + _directConnectSetMutex.lock(); + _directlyConnectedObjects.remove(listener.first); + _directConnectSetMutex.unlock(); + } + + } else { + qWarning() << "No listener found for packet type " << nameForPacketType(packet->getType()); + + // insert a dummy listener so we don't print this again + _packetListenerMap.insert(packet->getType(), { nullptr, QMetaMethod() }); + } + + _packetListenerLock.unlock(); + } diff --git a/libraries/networking/src/PacketReceiver.h b/libraries/networking/src/PacketReceiver.h index 9fdccdfddf..ac38749a88 100644 --- a/libraries/networking/src/PacketReceiver.h +++ b/libraries/networking/src/PacketReceiver.h @@ -44,9 +44,8 @@ public: bool registerListenerForTypes(const QSet& types, QObject* listener, const char* slot); bool registerListener(PacketType::Value type, QObject* listener, const char* slot); void unregisterListener(QObject* listener); - -public slots: - void processDatagrams(); + + void handleVerifiedPacket(std::unique_ptr packet); signals: void dataReceived(quint8 channelType, int bytes); diff --git a/libraries/networking/src/udt/Packet.cpp b/libraries/networking/src/udt/Packet.cpp index 02a44c4a4f..05b5f3fe50 100644 --- a/libraries/networking/src/udt/Packet.cpp +++ b/libraries/networking/src/udt/Packet.cpp @@ -98,12 +98,6 @@ Packet::Packet(const Packet& other) : QIODevice() { *this = other; - - if (other.isOpen()) { - this->open(other.openMode()); - } - - this->seek(other.pos()); } Packet& Packet::operator=(const Packet& other) { @@ -117,6 +111,12 @@ Packet& Packet::operator=(const Packet& other) { _payloadCapacity = other._payloadCapacity; _payloadSize = other._payloadSize; + + if (other.isOpen() && !isOpen()) { + open(other.openMode()); + } + + seek(other.pos()); return *this; } @@ -135,6 +135,12 @@ Packet& Packet::operator=(Packet&& other) { _payloadCapacity = other._payloadCapacity; _payloadSize = other._payloadSize; + + if (other.isOpen() && !isOpen()) { + open(other.openMode()); + } + + seek(other.pos()); return *this; } diff --git a/libraries/networking/src/udt/Socket.cpp b/libraries/networking/src/udt/Socket.cpp new file mode 100644 index 0000000000..2e1e3481f9 --- /dev/null +++ b/libraries/networking/src/udt/Socket.cpp @@ -0,0 +1,68 @@ +// +// Socket.cpp +// libraries/networking/src/udt +// +// Created by Stephen Birarda on 2015-07-20. +// 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 "Socket.h" + +#include "../NetworkLogging.h" + +using namespace udt; + +Socket::Socket(QObject* parent) : + QObject(parent) +{ + +} + +void Socket::rebind() { + quint16 oldPort = _udpSocket.localPort(); + + _udpSocket.close(); + _udpSocket.bind(QHostAddress::AnyIPv4, oldPort); +} + +void Socket::setBufferSizes(int numBytes) { + for (int i = 0; i < 2; i++) { + QAbstractSocket::SocketOption bufferOpt; + QString bufferTypeString; + + if (i == 0) { + bufferOpt = QAbstractSocket::SendBufferSizeSocketOption; + bufferTypeString = "send"; + + } else { + bufferOpt = QAbstractSocket::ReceiveBufferSizeSocketOption; + bufferTypeString = "receive"; + } + + int oldBufferSize = _udpSocket.socketOption(bufferOpt).toInt(); + + if (oldBufferSize < numBytes) { + int newBufferSize = _udpSocket.socketOption(bufferOpt).toInt(); + + qCDebug(networking) << "Changed socket" << bufferTypeString << "buffer size from" << oldBufferSize << "to" + << newBufferSize << "bytes"; + } else { + // don't make the buffer smaller + qCDebug(networking) << "Did not change socket" << bufferTypeString << "buffer size from" << oldBufferSize + << "since it is larger than desired size of" << numBytes; + } + } +} + +qint64 Socket::writeDatagram(const QByteArray& datagram, const HifiSockAddr& sockAddr) { + qint64 bytesWritten = _udpSocket.writeDatagram(datagram, sockAddr.getAddress(), sockAddr.getPort()); + + if (bytesWritten < 0) { + qCDebug(networking) << "ERROR in writeDatagram:" << _udpSocket.error() << "-" << _udpSocket.errorString(); + } + + return bytesWritten; +} diff --git a/libraries/networking/src/udt/Socket.h b/libraries/networking/src/udt/Socket.h new file mode 100644 index 0000000000..23ad75db12 --- /dev/null +++ b/libraries/networking/src/udt/Socket.h @@ -0,0 +1,55 @@ +// +// Socket.h +// libraries/networking/src/udt +// +// Created by Stephen Birarda on 2015-07-20. +// 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_Socket_h +#define hifi_Socket_h + +#include + +#include +#include + +#include "../HifiSockAddr.h" +#include "Packet.h" + +namespace udt { + +using VerifiedPacketFunction = std::function)>; + +class Socket : public QObject { + Q_OBJECT +public: + Socket(QObject* object = 0); + + quint16 localPort() const { return _udpSocket.localPort(); } + + qint64 writeDatagram(const char* data, qint64 size, const HifiSockAddr& sockAddr) + { return writeDatagram(QByteArray::fromRawData(data, size), sockAddr); } + qint64 writeDatagram(const QByteArray& datagram, const HifiSockAddr& sockAddr); + + void bind(const QHostAddress& address, quint16 port = 0) { _udpSocket.bind(address, port); } + void rebind(); + + void setVerifiedPacketFunction(VerifiedPacketFunction verifiedPacketFunction) + { _verifiedPacketFunction = verifiedPacketFunction; } + + void setBufferSizes(int numBytes); +private: + QUdpSocket _udpSocket { this }; + VerifiedPacketFunction _verifiedPacketFunction; +}; + +} + + +#endif // hifi_Socket_h