From b39559d86086f3b78fff66e5476553c315ba9a28 Mon Sep 17 00:00:00 2001 From: wangyix Date: Fri, 6 Jun 2014 17:44:30 -0700 Subject: [PATCH] packet recovery seems to be working Seems to impact FPS a lot. OctreeSceneStats is not being locked (causes freezing, need to find out why). --- .../src/octree/OctreeQueryNode.cpp | 5 --- .../src/octree/OctreeQueryNode.h | 4 ++- .../src/octree/OctreeSendThread.cpp | 3 +- assignment-client/src/octree/OctreeServer.cpp | 35 ++++++++++--------- interface/src/Application.cpp | 16 +++++---- libraries/networking/src/LimitedNodeList.cpp | 4 +-- libraries/networking/src/PacketHeaders.h | 3 +- 7 files changed, 37 insertions(+), 33 deletions(-) diff --git a/assignment-client/src/octree/OctreeQueryNode.cpp b/assignment-client/src/octree/OctreeQueryNode.cpp index 208be5951b..cf01e9a864 100644 --- a/assignment-client/src/octree/OctreeQueryNode.cpp +++ b/assignment-client/src/octree/OctreeQueryNode.cpp @@ -377,11 +377,6 @@ void OctreeQueryNode::packetSent(const QByteArray& packet) { _sequenceNumber++; } - -void OctreeQueryNode::addSequenceNumbersToResend(const QList& sequenceNumbers) { - _nackedSequenceNumbers.append(sequenceNumbers); -} - bool OctreeQueryNode::hasNextNackedPacket() const { return !_nackedSequenceNumbers.isEmpty(); } diff --git a/assignment-client/src/octree/OctreeQueryNode.h b/assignment-client/src/octree/OctreeQueryNode.h index e1707cc899..b79367503c 100644 --- a/assignment-client/src/octree/OctreeQueryNode.h +++ b/assignment-client/src/octree/OctreeQueryNode.h @@ -109,7 +109,9 @@ public: OCTREE_PACKET_SEQUENCE getSequenceNumber() const { return _sequenceNumber; } - void addSequenceNumbersToResend(const QList& sequenceNumbers); + void addNackedSequenceNumber(OCTREE_PACKET_SEQUENCE sequenceNumber) { + _nackedSequenceNumbers.append(sequenceNumber); + } bool hasNextNackedPacket() const; const QByteArray* getNextNackedPacket(); diff --git a/assignment-client/src/octree/OctreeSendThread.cpp b/assignment-client/src/octree/OctreeSendThread.cpp index e5c47f5d2d..cb8a773a64 100644 --- a/assignment-client/src/octree/OctreeSendThread.cpp +++ b/assignment-client/src/octree/OctreeSendThread.cpp @@ -305,7 +305,8 @@ int OctreeSendThread::resendNackedPackets(OctreeQueryNode* nodeData) { _totalWastedBytes += MAX_PACKET_SIZE - packet->size(); // ??? } } - + +if (packetsSent > 0) printf("\t\t re-sent %d packets!\n", packetsSent); return packetsSent; } diff --git a/assignment-client/src/octree/OctreeServer.cpp b/assignment-client/src/octree/OctreeServer.cpp index 46eb7aac16..8cf1649cdb 100644 --- a/assignment-client/src/octree/OctreeServer.cpp +++ b/assignment-client/src/octree/OctreeServer.cpp @@ -832,10 +832,9 @@ void OctreeServer::readPendingDatagrams() { PacketType packetType = packetTypeForPacket(receivedPacket); SharedNodePointer matchingNode = nodeList->sendingNodeForPacket(receivedPacket); if (packetType == getMyQueryMessageType()) { - // If we got a query packet, then we're talking to an agent, and we // need to make sure we have it in our nodeList. - if (matchingNode) { + if (matchingNode) { nodeList->updateNodeWithDataFromPacket(matchingNode, receivedPacket); OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData(); if (nodeData && !nodeData->isOctreeSendThreadInitalized()) { @@ -852,25 +851,29 @@ void OctreeServer::readPendingDatagrams() { } else if (packetType == PacketTypeOctreeDataNack) { // parse packet for sequence numbers that need to be resent -int numBytesPacketHeader = numBytesForPacketHeader(receivedPacket); -const unsigned char* dataAt = reinterpret_cast(receivedPacket.data()) + numBytesPacketHeader; -uint16_t numSequenceNumbers = (*(uint16_t*)dataAt); -dataAt += sizeof(uint16_t); +if (matchingNode) { -// read sequence numbers -QList sequenceNumbers; -for (int i = 0; i < numSequenceNumbers; i++) { - OCTREE_PACKET_SEQUENCE sequenceNumber = (*(OCTREE_PACKET_SEQUENCE*)dataAt); - sequenceNumbers.append(sequenceNumber); - dataAt += sizeof(OCTREE_PACKET_SEQUENCE); + OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData(); -printf("\t\t\t nacked packet: seq = %d\n", sequenceNumber); + int numBytesPacketHeader = numBytesForPacketHeader(receivedPacket); + const unsigned char* dataAt = reinterpret_cast(receivedPacket.data()) + numBytesPacketHeader; + + uint16_t numSequenceNumbers = (*(uint16_t*)dataAt); + dataAt += sizeof(uint16_t); + +printf("\t received nack packet containing %d seq nums\n", numSequenceNumbers); + + // read sequence numbers + for (int i = 0; i < numSequenceNumbers; i++) { + OCTREE_PACKET_SEQUENCE sequenceNumber = (*(OCTREE_PACKET_SEQUENCE*)dataAt); + nodeData->addNackedSequenceNumber(sequenceNumber); + dataAt += sizeof(OCTREE_PACKET_SEQUENCE); + +printf("\t seq = %d\n", sequenceNumber); + } } -OctreeQueryNode* nodeData = (OctreeQueryNode*)matchingNode->getLinkedData(); // move this or something -nodeData->addSequenceNumbersToResend(sequenceNumbers); - } else if (packetType == PacketTypeJurisdictionRequest) { diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 07bef852f2..a28343eb96 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -2110,8 +2110,6 @@ void Application::updateMyAvatar(float deltaTime) { void Application::sendNack() { -printf("\n\t sendNack()...\n"); - char packet[MAX_PACKET_SIZE]; NodeList* nodeList = NodeList::getInstance(); @@ -2124,15 +2122,18 @@ printf("\n\t sendNack()...\n"); || node->getType() == NodeType::ModelServer) ) { - _octreeSceneStatsLock.lockForWrite(); + //_octreeSceneStatsLock.lockForWrite(); OctreeSceneStats& stats = _octreeServerSceneStats[node->getUUID()]; + int numSequenceNumbersAvailable = stats.getNumSequenceNumbersToNack(); + if (numSequenceNumbersAvailable == 0) + continue; char* dataAt = packet; int bytesRemaining = MAX_PACKET_SIZE; // pack header - int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeOctreeDataNack, node->getUUID()); + int numBytesPacketHeader = populatePacketHeader(packet, PacketTypeOctreeDataNack); dataAt += numBytesPacketHeader; bytesRemaining -= numBytesPacketHeader; @@ -2140,12 +2141,13 @@ printf("\n\t sendNack()...\n"); // calculate and pack number of sequence numbers - uint16_t numSequenceNumbers = min(stats.getNumSequenceNumbersToNack(), numPacketsRoomFor); + uint16_t numSequenceNumbers = min(numSequenceNumbersAvailable, numPacketsRoomFor); uint16_t* numSequenceNumbersAt = (uint16_t*)dataAt; *numSequenceNumbersAt = numSequenceNumbers; dataAt += sizeof(uint16_t); // pack sequence numbers +printf("\n\t sending nack...\n"); printf("\t\t packed %d seq #s:", numSequenceNumbers); for (int i = 0; i < numSequenceNumbers; i++) { OCTREE_PACKET_SEQUENCE* sequenceNumberAt = (OCTREE_PACKET_SEQUENCE*)dataAt; @@ -2155,10 +2157,10 @@ printf(" %d,", *sequenceNumberAt); } printf("\n"); - _octreeSceneStatsLock.unlock(); + //_octreeSceneStatsLock.unlock(); // make sure we still have an active socket???? - nodeList->writeUnverifiedDatagram(packet, dataAt - packet, node); + nodeList->writeUnverifiedDatagram(packet, dataAt-packet, node); } } } diff --git a/libraries/networking/src/LimitedNodeList.cpp b/libraries/networking/src/LimitedNodeList.cpp index f9630c9102..15cebc26ac 100644 --- a/libraries/networking/src/LimitedNodeList.cpp +++ b/libraries/networking/src/LimitedNodeList.cpp @@ -274,13 +274,13 @@ qint64 LimitedNodeList::writeDatagram(const char* data, qint64 size, const Share qint64 LimitedNodeList::writeDatagram2(int seq, const char* data, qint64 size, const SharedNodePointer& destinationNode, const HifiSockAddr& overridenSockAddr) { - qint64 ret; + qint64 ret = -1; if (randFloat() < 0.8f) { ret = writeDatagram(QByteArray(data, size), destinationNode, overridenSockAddr); } else { - printf("\t\t\t dropped packet seq = %d!!!\n", seq); + printf("dropped packet seq = %d --------------------------\n", seq); } diff --git a/libraries/networking/src/PacketHeaders.h b/libraries/networking/src/PacketHeaders.h index a73ffe8564..eac2f88870 100644 --- a/libraries/networking/src/PacketHeaders.h +++ b/libraries/networking/src/PacketHeaders.h @@ -75,7 +75,8 @@ const QSet NON_VERIFIED_PACKETS = QSet() << PacketTypeDomainServerRequireDTLS << PacketTypeDomainConnectRequest << PacketTypeDomainList << PacketTypeDomainListRequest << PacketTypeDomainOAuthRequest << PacketTypeCreateAssignment << PacketTypeRequestAssignment << PacketTypeStunResponse - << PacketTypeNodeJsonStats << PacketTypeVoxelQuery << PacketTypeParticleQuery << PacketTypeModelQuery; + << PacketTypeNodeJsonStats << PacketTypeVoxelQuery << PacketTypeParticleQuery << PacketTypeModelQuery +<< PacketTypeOctreeDataNack; const int NUM_BYTES_MD5_HASH = 16; const int NUM_STATIC_HEADER_BYTES = sizeof(PacketVersion) + NUM_BYTES_RFC4122_UUID;