Changeset 7954 in orxonox.OLD for trunk/src/lib/network/connection_monitor.cc
- Timestamp:
- May 29, 2006, 3:28:41 PM (19 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/lib/network/connection_monitor.cc
r5822 r7954 10 10 11 11 ### File Specific: 12 main-programmer: Silvan Nellen12 main-programmer: Christoph Renner 13 13 co-programmer: ... 14 14 */ 15 15 16 16 #include "connection_monitor.h" 17 #include "network_log.h" 18 17 19 #include <debug.h> 18 20 #include <SDL/SDL.h> … … 22 24 using namespace std; 23 25 24 ConnectionMonitor::ConnectionMonitor() 25 { 26 26 /** 27 * constructor 28 * @param userId user's id 29 */ 30 ConnectionMonitor::ConnectionMonitor( int userId ) 31 { 27 32 /* set the class id for the base object and add ist to class list*/ 28 33 this->setClassID(CL_CONNECTION_MONITOR, "ConnectionMonitor"); 29 30 /*initialize variables*/ 31 32 /*Data of the lifetime of the ConnectionMonitor Object*/ 33 packetToAverage = 100; 34 protocollType = "default(TCP)"; 35 36 startTime= SDL_GetTicks(); 37 totalReceivedPackets=0; 38 averageDatarate=0; 39 totalLostPackets=0; 40 totalPacketloss=0; 41 42 /*Data of the current packet*/ 43 currentPacketID=0; 44 currentPacketTick=0; 45 lastPacketID=0; 46 lastPacketTick=0; 47 currentDelay=0; 48 49 /*Data of the last n packets (n is specified by paxketsToAverage)*/ 50 sizeOfLastFewPackets=0; 51 currentDatarate=0; 52 lastFewDelays = new unsigned int [packetToAverage]; 53 lastFewPackets = new byte* [packetToAverage]; 54 packetCounter=0; 55 56 57 } 58 59 60 ConnectionMonitor::~ConnectionMonitor() 61 { 62 63 64 } 65 66 67 68 void ConnectionMonitor::processPacket(byte* currentPacket, unsigned int packetLength) 69 { 70 /*Process the current Packet*/ 71 currentPacketTick = SDL_GetTicks(); 72 currentDelay = currentPacketTick - lastPacketTick; 73 74 /*Do whats needed for Averaging*/ 75 76 if(packetCounter == packetToAverage) 77 { 78 computeCurrentDatarate(); 79 displayStatistic(); 80 packetCounter = 0; 81 sizeOfLastFewPackets = 0; 82 } 83 84 lastFewDelays[packetCounter] = currentDelay; 85 lastFewPackets[packetCounter] = currentPacket; 86 sizeOfLastFewPackets += packetLength; 87 88 /*Update the lifetime Variables*/ 89 totalReceivedPackets ++; 90 float timeDiff = this->currentPacketTick - this->startTime; 91 if( timeDiff != 0.0f ) 92 averageDatarate = totalReceivedPackets/timeDiff; 93 94 /*Preparefor the next Packet*/ 95 lastPacketTick = currentPacketTick; 96 packetCounter++; 97 } 98 99 100 /* Compute the value of current Datarate*/ 101 void ConnectionMonitor::computeCurrentDatarate() 102 { 103 int timeForLastFewPackets=0; 104 for(int i=0;i < packetToAverage;i++) 105 timeForLastFewPackets += lastFewDelays[i]; 106 107 if( timeForLastFewPackets != 0) 108 currentDatarate = sizeOfLastFewPackets/timeForLastFewPackets; 109 } 110 111 void doUDPRelatedStuff() 112 { 113 /* Do protocol related stuff 114 115 Only for Udp: 116 "currentPacketID = getID from package"; 117 118 if(currentPacketID - lastPacketID > 1) 34 35 this->userId = userId; 36 this->ping = 0; 37 this->incomingUnzippedBandWidth = 0; 38 this->outgoingUnzippedBandWidth = 0; 39 this->incomingZippedBandWidth = 0; 40 this->outgoingZippedBandWidth = 0; 41 this->nIncomingPackets = 0; 42 this->nOutgoingPackets = 0; 43 this->nZIncomingPackets = 0; 44 this->nZOutgoingPackets = 0; 45 46 this->lastPacketTick = 0; 47 this->lastPrintTick = 0; 48 } 49 50 /** 51 * deconstructor 52 */ 53 ConnectionMonitor::~ConnectionMonitor( ) 54 { 55 } 56 57 /** 58 * process unzipped outgoing packet 59 * @param data pointer to packet data 60 * @param length length of packet 61 * @param stateId packet's state id 62 */ 63 void ConnectionMonitor::processUnzippedOutgoingPacket( byte * data, int length, int stateId ) 64 { 65 int tick = SDL_GetTicks(); 66 67 nOutgoingPackets++; 68 69 // for ping calculation 70 sentStateTicks[stateId] = tick; 71 72 // calculate bandwidth 73 outgoingUnzippedPacketHistory[tick] = length; 74 outgoingUnzippedBandWidth = calculateBandWidth( outgoingUnzippedPacketHistory, tick ); 75 76 //NETPRINTF(n)("UNZIPPED UPSTREAM: user: %d bandwidth %f\n", userId, outgoingUnzippedBandWidth ); 77 78 // count zero bytes 79 int nZeroBytes = 0; 80 81 for ( int i = 0; i < length; i++ ) 82 if ( data[i] == '\0' ) 83 nZeroBytes++; 84 85 //NETPRINTF(n)( "ZEROBYTES: %d (%f%%)\n", nZeroBytes, ((float)100)*nZeroBytes/length ); 86 } 87 88 /** 89 * process unzipped incoming packet 90 * @param data pointer to packet data 91 * @param length length of packet 92 * @param stateId packet's state id 93 * @param ackedState state which was acked by this packet 94 */ 95 void ConnectionMonitor::processUnzippedIncomingPacket( byte * data, int length, int stateId, int ackedState ) 96 { 97 int tick = SDL_GetTicks(); 98 99 nIncomingPackets++; 100 101 lastPacketTick = tick; 102 103 // calculate ping 104 if ( sentStateTicks.find( ackedState ) != sentStateTicks.end() ) 119 105 { 120 totalLostPackets += currentPacketID - lastPacketID; 121 } 122 123 totalPacketloss = (totalLostPackets/totalReceivedPackets)*100 ; 124 */ 125 } 126 127 128 129 /* Display connectoin statistic*/ 130 void ConnectionMonitor::displayStatistic() 131 { 132 // PRINT(0)("============================================\n"); 133 // PRINT(0)("Connection Monitor Network Statistics:\n"); 134 // PRINT(0)("Total received packets:",totalReceivedPackets); 135 // PRINT(0)("Average datarate :\n",averageDatarate); 136 // PRINT(0)("Total lost packets:",totalLostPackets); 137 // PRINT(0)("Packetloss [%] :\n",totalPacketloss); 138 // 139 // PRINT(0)("Current datarate :\n",currentDatarate); 140 // PRINT(0)("Delays of the last few packets :\n"); 141 // for(int i=1 ;i <= packetToAverage-1;i++) 142 // PRINT(0)("%i ",lastFewDelays[i]); 143 // 144 // PRINT(0)("============================================\n"); 145 146 } 147 106 ackDelay.push_back( tick - sentStateTicks[ackedState] ); 107 } 108 109 while ( sentStateTicks.begin() != sentStateTicks.end() && sentStateTicks.begin()->first <= ackedState ) 110 sentStateTicks.erase( sentStateTicks.begin() ); 111 112 while ( ackDelay.size() > N_PACKETS_FOR_PING ) 113 ackDelay.erase( ackDelay.begin() ); 114 115 ping = 0; 116 117 for ( std::list<int>::iterator it = ackDelay.begin(); it != ackDelay.end(); it++ ) 118 ping += *it; 119 120 if ( ackDelay.size() == 0 ) 121 ping = -1; 122 else 123 ping /= ackDelay.size(); 124 125 //NETPRINTF(n)("PING: user: %d ping: %d\n", userId, ping ); 126 127 // calculate bandwidth 128 incomingUnzippedPacketHistory[tick] = length; 129 incomingUnzippedBandWidth = calculateBandWidth( incomingUnzippedPacketHistory, tick ); 130 131 //NETPRINTF(n)("UNZIPPED DOWNSTREAM: user: %d bandwidth %f\n", userId, incomingUnzippedBandWidth ); 132 133 } 134 135 /** 136 * calculate bandwidth out of packethistory 137 * @param packetHistory packet history 138 * @param tick current tick from SDL_GetTicks 139 * @return bandwidth in bytes/sec 140 */ 141 float ConnectionMonitor::calculateBandWidth( std::map< int, int > packetHistory, int tick ) 142 { 143 // delete old packets 144 while ( packetHistory.begin()->first < tick - MSECS_TO_CALC_BWIDTH ) 145 packetHistory.erase( packetHistory.begin() ); 146 147 float res = 0.0f; 148 149 for ( std::map<int,int>::iterator it = packetHistory.begin(); it != packetHistory.end(); it++ ) 150 { 151 res += it->second; 152 } 153 154 if ( packetHistory.size() <= 1 || tick - packetHistory.begin()->first == 0 ) 155 res = 0.0f; 156 else 157 res /= (float)((tick - packetHistory.begin()->first)*( 1 + 1/((float)(packetHistory.size()-1)) )); 158 159 res *= 1000.0f; 160 161 return res; 162 } 163 164 165 /** 166 * process zipped outgoing packet 167 * @param data pointer to packet data 168 * @param length length of packet 169 * @param stateId packet's state id 170 */ 171 void ConnectionMonitor::processZippedOutgoingPacket( byte * data, int length, int stateId ) 172 { 173 int tick = SDL_GetTicks(); 174 175 nZOutgoingPackets++; 176 177 // calculate bandwidth 178 outgoingZippedPacketHistory[tick] = length; 179 outgoingZippedBandWidth = calculateBandWidth( outgoingZippedPacketHistory, tick ); 180 181 //NETPRINTF(n)("UPSTREAM: user: %d bandwidth %f nOutgoingPackets %d\n", userId, outgoingZippedBandWidth, nOutgoingPackets ); 182 183 if ( lastPrintTick < tick-1000 ) 184 { 185 printStatis(); 186 lastPrintTick = tick; 187 } 188 } 189 190 191 /** 192 * process zipped incoming packet 193 * @param data pointer to packet data 194 * @param length length of packet 195 * @param stateId packet's state id 196 * @param ackedState state which was acked by this packet 197 */ 198 void ConnectionMonitor::processZippedIncomingPacket( byte * data, int length, int stateId, int ackedState ) 199 { 200 int tick = SDL_GetTicks(); 201 202 nZIncomingPackets++; 203 204 // calculate bandwidth 205 incomingZippedPacketHistory[tick] = length; 206 incomingZippedBandWidth = calculateBandWidth( incomingZippedPacketHistory, tick ); 207 208 //NETPRINTF(n)("DOWNSTREAM: user: %d bandwidth %f nIncomingPackets %d\n", userId, incomingZippedBandWidth, nIncomingPackets ); 209 210 } 211 212 213 /** 214 * check if client sent no packets for SECS_TO_TIMEOUT 215 * @return true if last packet recieved \< NOW() - SECS_TO_TIMEOUT 216 */ 217 bool ConnectionMonitor::hasTimedOut( ) 218 { 219 if ( lastPacketTick + SECS_TO_TIMEOUT*1000 < SDL_GetTicks() && nIncomingPackets > 0 ) 220 return true; 221 222 if ( nIncomingPackets == 0 && nOutgoingPackets >= NETWORK_FREQUENCY*SECS_TO_TIMEOUT ) 223 return true; 224 225 return false; 226 } 227 228 229 230 /** 231 * prints bandwith usage, ping and other important things to telnet-console 232 */ 233 void ConnectionMonitor::printStatis( ) 234 { 235 NETPRINT(n)("=========NETWORKSTATS FOR USER %d=========\n", userId); 236 NETPRINT(n)("PING = %d\n", ping); 237 NETPRINT(n)("BANDWIDTH: UP: %f (%f) DOWN %f (%f)\n", outgoingZippedBandWidth, outgoingUnzippedBandWidth, incomingZippedBandWidth, incomingUnzippedBandWidth); 238 NETPRINT(n)("=========================================="); 239 } 240 241
Note: See TracChangeset
for help on using the changeset viewer.