Alex Bikfalvi
SimStream Documentation
HostFlow.cpp
00001 #include "Headers.h" 00002 #include "HostFlow.h" 00003 #include "RouteHost.h" 00004 #include "PacketDummy.h" 00005 #include "Console.h" 00006 #include "Debug.h" 00007 00008 CHostFlow::CHostFlow( 00009 __uint32 id, 00010 CSimHandler* sim, 00011 CAddress address, 00012 CInfo* info 00013 ) : CNode(id, sim, address, 1, &CRouteHost::route, info) 00014 { 00015 // Delegates 00016 this->delegateRecv = new Delegate4<CHostFlow, void, __uint32, CPacketIp*, CPacketUdp*, CPacket*>(this, &CHostFlow::Recv); 00017 this->delegateConnectionRecv = new Delegate2<CHostFlow, void, CConnectionReceiver*, CPacket*>(this, &CHostFlow::ConnectionRecv); 00018 this->delegateAccept = new Delegate2<CHostFlow, bool, CAddress, CPacket*>(this, &CHostFlow::ConnectionAccept); 00019 this->delegateAccepted = new Delegate1<CHostFlow, void, CConnectionSender*>(this, &CHostFlow::ConnectionAccepted); 00020 this->delegateOpen = new Delegate2<CHostFlow, void, CConnection*, CConnection::EOpenResult>(this, &CHostFlow::ConnectionOpen); 00021 this->delegateClose = new Delegate2<CHostFlow, void, CConnection*, CConnection::ECloseResult>(this, &CHostFlow::ConnectionClose); 00022 00023 // UDP layer 00024 (*this->layerUdp->EventRecv()) += this->delegateRecv; 00025 00026 // Info 00027 this->streamRate = 500000; 00028 this->packetRate = 25; 00029 this->packetInterval = 1.0/this->packetRate; 00030 this->packetSize = (__uint32)ceil(this->streamRate / this->packetRate); 00031 this->connectionsMax = 10; 00032 this->port = 0; 00033 this->packetIndex[0] = 0; 00034 this->packetIndex[1] = 0; 00035 this->packets = 0; 00036 00037 // Connection layer 00038 this->connectionLayer = new CConnectionLayer( 00039 this->sim, 00040 this->port, // port 00041 this->connectionsMax, // connections max 00042 this->layerUdp->DelegateSend(), 00043 this->delegateConnectionRecv, 00044 this->delegateAccept, 00045 this->delegateAccepted, 00046 this->packetSize // sender segment size 00047 ); 00048 00049 // Connections 00050 this->receiver = NULL; 00051 this->senders[0] = NULL; 00052 this->senders[1] = NULL; 00053 this->senderIndex = 0; 00054 00055 // Timer 00056 this->timers[0] = new CTimer<CHostFlow>(this->sim, this, &CHostFlow::Timer); 00057 this->timers[1] = new CTimer<CHostFlow>(this->sim, this, &CHostFlow::Timer); 00058 00059 // Data 00060 char fileName[256]; 00061 sprintf(fileName, "host_%u_sender.dat", this->id); 00062 if(FILE_OPEN(this->fileSender, fileName, "w")) { printf("\nCannot create file \'%s\'.", fileName); exit(-1); } 00063 00064 sprintf(fileName, "host_%u_receiver.dat", this->id); 00065 if(FILE_OPEN(this->fileReceiver, fileName, "w")) { printf("\nCannot create file \'%s\'.", fileName); exit(-1); } 00066 00067 // Delegates 00068 this->delegateSenderSend = new Delegate2<CHostFlow, void, CConnectionSender*, CPacket*>(this, &CHostFlow::SenderSend); 00069 } 00070 00071 CHostFlow::~CHostFlow() 00072 { 00073 // Connection layer 00074 delete this->connectionLayer; 00075 00076 // Delegates 00077 delete this->delegateRecv; 00078 delete this->delegateConnectionRecv; 00079 delete this->delegateAccept; 00080 delete this->delegateAccepted; 00081 delete this->delegateOpen; 00082 delete this->delegateClose; 00083 00084 // Timer 00085 delete this->timers[0]; 00086 delete this->timers[1]; 00087 00088 // Data 00089 fclose(this->fileSender); 00090 fclose(this->fileReceiver); 00091 00092 // Delegates 00093 delete this->delegateSenderSend; 00094 } 00095 00096 void CHostFlow::Connect(CAddress dst) 00097 { 00098 assert(NULL == this->receiver); 00099 00100 #ifdef LOG 00101 printf("\nT = %8.3lf\tPEER %u CONNECT %u:%u : ", this->sim->Time(), this->address.Address(), dst.Address(), 100); 00102 #endif 00103 00104 // Create receiver connection 00105 switch(this->connectionLayer->Create(dst, this->port, &this->receiver)) 00106 { 00107 case CConnectionLayer::SUCCESS: 00108 #ifdef LOG 00109 CConsole::SetColor(CConsole::LIGHT_GREEN); 00110 printf("SUCCESS"); 00111 CConsole::SetColor(CConsole::LIGHT_GRAY); 00112 #endif 00113 00114 // Add events to the connection 00115 (*this->receiver->EventOpen()) += this->delegateOpen; 00116 (*this->receiver->EventClose()) += this->delegateClose; 00117 00118 // Open the connection 00119 this->receiver->Open(); 00120 00121 break; 00122 case CConnectionLayer::FAIL_MAX_CONNECTIONS_REACHED: 00123 #ifdef LOG 00124 CConsole::SetColor(CConsole::LIGHT_RED); 00125 printf("FAIL"); 00126 CConsole::SetColor(CConsole::LIGHT_GRAY); 00127 #endif 00128 break; 00129 } 00130 00131 } 00132 00133 void CHostFlow::DisconnectSender(__uint8 sender) 00134 { 00135 #ifdef LOG 00136 printf("\nT = %8.3lf\tPEER %u DISCONNECT SENDER %s", this->sim->Time(), this->address.Address(), this->senders[sender]->ToString()); 00137 #endif 00138 this->senders[sender]->Close(); 00139 } 00140 00141 void CHostFlow::DisconnectReceiver() 00142 { 00143 #ifdef LOG 00144 printf("\nT = %8.3lf\tPEER %u DISCONNECT RECEIVER %s", this->sim->Time(), this->address.Address(), this->receiver->ToString()); 00145 #endif 00146 this->receiver->Close(); 00147 } 00148 00149 void CHostFlow::Finalize() 00150 { 00151 // Call the base class finalizer 00152 CNode::Finalize(); 00153 } 00154 00155 void CHostFlow::ConnectionRecv(CConnectionReceiver* connection, CPacket* packet) 00156 { 00157 #ifdef LOG_VERBOSE 00158 CConsole::SetColor(CConsole::LIGHT_CYAN); 00159 printf("\nT = %8.3lf\tPEER %u RECV on %s %u bits (%s) : %u : ", this->sim->Time(), this->address.Address(), connection->ToString(), packet->Size(), packet->ToString(), this->packets++); 00160 CConsole::SetColor(CConsole::LIGHT_MAGENTA); 00161 printf(" : %lf bps", this->Link(0)->MeterUtil(1)); 00162 CConsole::SetColor(CConsole::LIGHT_GRAY); 00163 #endif 00164 // Data 00165 fprintf(this->fileReceiver, "%.9lf %u %lf %u\n", 00166 this->sim->Time(), 00167 packet->Size(), 00168 this->Link(0)->MeterUtil(1), 00169 this->Link(0)->MeterQueue(1, 1)); 00170 } 00171 00172 bool CHostFlow::ConnectionAccept(CAddress src, CPacket* packet) 00173 { 00174 #ifdef LOG 00175 printf("\nT = %8.3lf\tPEER %u ACCEPT %u", this->sim->Time(), this->address.Address(), src.Address()); 00176 #endif 00177 return true; 00178 } 00179 00180 void CHostFlow::ConnectionAccepted(CConnectionSender* connection) 00181 { 00182 #ifdef LOG 00183 printf("\nT = %8.3lf\tPEER %u ACCEPTED %s", this->sim->Time(), this->address.Address(), connection->ToString()); 00184 #endif 00185 00186 assert(this->senderIndex < 2); 00187 // Set the sender 00188 this->senders[this->senderIndex] = connection; 00189 00190 // Set events 00191 (*this->senders[this->senderIndex]->EventOpen()) += this->delegateOpen; 00192 (*this->senders[this->senderIndex]->EventClose()) += this->delegateClose; 00193 (*this->senders[this->senderIndex]->EventSend()) += this->delegateSenderSend; 00194 this->senderIndex++; 00195 } 00196 00197 void CHostFlow::ConnectionOpen(CConnection* connection, CConnection::EOpenResult result) 00198 { 00199 #ifdef LOG 00200 printf("\nT = %8.3lf\tPEER %u OPENED %s : ", this->sim->Time(), this->address.Address(), connection->ToString()); 00201 #endif 00202 00203 switch(result) 00204 { 00205 case CConnection::OPEN_SUCCESS: 00206 #ifdef LOG 00207 CConsole::SetColor(CConsole::LIGHT_GREEN); 00208 printf("SUCCESS"); 00209 CConsole::SetColor(CConsole::LIGHT_GRAY); 00210 #endif 00211 break; 00212 case CConnection::OPEN_CANCELED: 00213 #ifdef LOG 00214 CConsole::SetColor(CConsole::LIGHT_YELLOW); 00215 printf("CANCELED"); 00216 CConsole::SetColor(CConsole::LIGHT_GRAY); 00217 #endif 00218 break; 00219 case CConnection::OPEN_FAIL_TIMEOUT: 00220 #ifdef LOG 00221 CConsole::SetColor(CConsole::LIGHT_RED); 00222 printf("FAIL_TIMEOUT"); 00223 CConsole::SetColor(CConsole::LIGHT_GRAY); 00224 #endif 00225 break; 00226 case CConnection::OPEN_FAIL_REMOTE: 00227 #ifdef LOG 00228 CConsole::SetColor(CConsole::LIGHT_RED); 00229 printf("FAIL_REMOTE"); 00230 CConsole::SetColor(CConsole::LIGHT_GRAY); 00231 #endif 00232 break; 00233 } 00234 } 00235 00236 void CHostFlow::ConnectionClose(CConnection* connection, CConnection::ECloseResult result) 00237 { 00238 #ifdef LOG 00239 printf("\nT = %8.3lf\tPEER %u CLOSED %s : ", this->sim->Time(), this->address.Address(), connection->ToString()); 00240 #endif 00241 00242 switch(result) 00243 { 00244 case CConnection::CLOSE_CONFIRMED: 00245 #ifdef LOG 00246 CConsole::SetColor(CConsole::LIGHT_YELLOW); 00247 printf("CONFIRMED"); 00248 CConsole::SetColor(CConsole::LIGHT_GRAY); 00249 #endif 00250 break; 00251 case CConnection::CLOSE_TIMEOUT: 00252 #ifdef LOG 00253 CConsole::SetColor(CConsole::LIGHT_RED); 00254 printf("TIMEOUT"); 00255 CConsole::SetColor(CConsole::LIGHT_GRAY); 00256 #endif 00257 break; 00258 case CConnection::CLOSE_COMPLETE: 00259 #ifdef LOG 00260 CConsole::SetColor(CConsole::LIGHT_GREEN); 00261 printf("COMPLETE"); 00262 CConsole::SetColor(CConsole::LIGHT_GRAY); 00263 #endif 00264 00265 printf("\n\nPEER %u\tuplink: %llu\tdownlink: %llu", this->address.Address(), 00266 this->Link(0)->StatBits(0, 0) + this->Link(0)->StatBits(1, 0), 00267 this->Link(0)->StatBits(0, 1) + this->Link(0)->StatBits(1, 1) 00268 ); 00269 00270 break; 00271 } 00272 } 00273 00274 void CHostFlow::Recv(__uint32 entry, CPacketIp* ip, CPacketUdp* udp, CPacket* packet) 00275 { 00276 assert(packet); 00277 00278 switch(packet->Type()) 00279 { 00280 // Pass all connection packets to the connection layer 00281 case PACKET_TYPE_CONNECTION: this->connectionLayer->Recv(ip->Src(), udp->Src(), udp->Dst(), type_cast<CPacketConnection*>(packet)); break; 00282 default: assert(0); 00283 } 00284 } 00285 00286 void CHostFlow::StartFlow(__uint8 sender) 00287 { 00288 #ifdef LOG 00289 printf("\nT = %8.3lf\tPEER %u START FLOW %s", this->sim->Time(), this->address.Address(), senders[sender]->ToString()); 00290 #endif 00291 00292 // Start sending packets 00293 this->Timer((CTimerInfo*)sender); 00294 } 00295 00296 void CHostFlow::StopFlow(__uint8 sender) 00297 { 00298 #ifdef LOG 00299 printf("\nT = %8.3lf\tPEER %u STOP FLOW %s", this->sim->Time(), this->address.Address(), senders[sender]->ToString()); 00300 #endif 00301 00302 // Stop sending packets 00303 if(this->timers[sender]->IsSet()) this->timers[sender]->Cancel(); 00304 } 00305 00306 void CHostFlow::Timer(CTimerInfo* info) 00307 { 00308 __uint32 sender = 0; //(__uint32)info; 00309 00310 // Transmit one packet using the connection 00311 CPacketDummy* packet = new CPacketDummy(this->packetSize, this->packetIndex[0]++); 00312 00313 #ifdef LOG_VERBOSE 00314 printf("\nT = %8.3lf\tPEER %u SEND on %s %u bits (%s) : %u : ", this->sim->Time(), this->address.Address(), senders[sender]->ToString(), packet->Size(), packet->ToString(), this->packets++); 00315 #endif 00316 00317 CConnectionSender::EResult result = this->senders[sender]->Send(packet); 00318 00319 switch(result) 00320 { 00321 case CConnectionSender::SEND_SUCCESS: 00322 #ifdef LOG_VERBOSE 00323 CConsole::SetColor(CConsole::LIGHT_GREEN); 00324 printf("\nSUCCESS"); 00325 CConsole::SetColor(CConsole::LIGHT_GRAY); 00326 #endif 00327 break; 00328 case CConnectionSender::SEND_FAIL_NOT_OPEN: 00329 #ifdef LOG_VERBOSE 00330 CConsole::SetColor(CConsole::LIGHT_RED); 00331 printf("\nFAIL_NOT_OPEN"); 00332 CConsole::SetColor(CConsole::LIGHT_GRAY); 00333 #endif 00334 break; 00335 } 00336 00337 #ifdef LOG_VERBOSE 00338 CConsole::SetColor(CConsole::LIGHT_MAGENTA); 00339 printf(" : %lf bps", this->Link(0)->MeterUtil(0)); 00340 CConsole::SetColor(CConsole::LIGHT_GRAY); 00341 #endif 00342 // Schedule next timer 00343 this->timers[sender]->SetAfter(this->packetInterval, (CTimerInfo*)sender); 00344 } 00345 00346 void CHostFlow::SenderSend(CConnectionSender* sender, CPacket* packet) 00347 { 00348 // Data 00349 fprintf(this->fileSender, "%.9lf %u %.9lf %u %.9lf %.9lf %.9lf\n", 00350 this->sim->Time(), 00351 packet->Size(), 00352 this->Link(0)->MeterUtil(0), 00353 this->Link(0)->MeterQueue(1, 0), 00354 sender->StatFlowRtt(), 00355 sender->StatFlowRate(), 00356 sender->StatFlowLossRate()); 00357 }
Last updated: February 8, 2011