#include "Lan.h" #include "Node.h" #include "Packet.h" #include <iostream> #include <stdlib.h> #include <time.h> Lan::Lan( int bandwidth ): max_bandwidth_( bandwidth ), used_bandwidth_( 0 ) { cout << "Lan con banda massima " << bandwidth << "p" << endl; // eventuale inizializzazione del vettore cout << "Nessun nodo nella Lan" << endl; } Lan::Lan(const vector< Node *>& nodesvect): max_bandwidth_( 10 ), used_bandwidth_( 0 ), nodesVect_( nodesvect ) { // se non è fornita la banda della lan // si assume che sia di 10 pacchetti cout << "Lan con banda massima 10p" << " e " << nodesvect.size() << " nodi" << endl; } Lan::Lan( int bandwidth, const vector< Node *>& nodesvect): max_bandwidth_( bandwidth ), used_bandwidth_( 0 ), nodesVect_( nodesvect ) { cout << "Lan con banda massima " << bandwidth << "p" << " e " << nodesvect.size() << " nodi" << endl; } Lan::~Lan() { vector<Node *>::iterator i; for( i = nodesVect_.begin(); i != nodesVect_.end(); i++ ) { delete *i; } while( !packetQueue_.empty() ) { // distruzione dei pacchetti in coda // si sarebbe anche potuto decidere // di recapitarli, invece di distruggerli const Packet *packet = packetQueue_.front(); packetQueue_.pop(); delete packet; } cout << "Lan distrutta" << endl; } void Lan:: addNode( Node* node) { nodesVect_.push_back( node ); } int Lan::bandWidth() const { return (max_bandwidth_ - used_bandwidth_); } bool Lan::enqueue(const Packet *packet ) { bool enqueued; // se c'e' banda disponibile si accoda il pacchetto // altrimenti lo si rifiuta if( bandWidth() > 0 ) { packetQueue_.push( packet ); used_bandwidth_++; enqueued = true; } else { // cout << "Pacchetto rifiutato" << endl; enqueued = false; } return enqueued; } bool Lan::deliverPacket() { // se tutta la banda e' libera si esce con successo // si assume che non vi siano pacchetti in coda // e che quindi siano stati precedentemente recapitati if( bandWidth() == max_bandwidth_ ) return true; //se si arriva a questo punto vuol dire che //vi sono pacchetti in coda da recapitare //cout << "Debug_prima: " << packetQueue_.size() << endl; const Packet *packet = packetQueue_.front(); packetQueue_.pop(); //cout << "Debug_dopo: " << packetQueue_.size() << endl; used_bandwidth_--; int nodenum = nodesVect_.size(); bool delivered = false; for(int i = 0; (i < nodenum) && !delivered; i++) { //cout << "--> nel for" << i << endl; if( nodesVect_[i]->accept( *packet ) ) delivered = true; } if( !delivered ) cout << "Pacchetto " << packet->getInfo() << " ha destinazione sconosciuta" << endl; delete packet; return delivered; } void Lan::doWork() { // se e' una lan con banda massima 0 allora si esce if( max_bandwidth_ == 0 ) return; Node* currentNode; int nodesNum = nodesVect_.size(); //cout << "dimensione: " << nodesNum << endl; // l'indice j segnala il numero di iterazioni // a partire dal nodo i, l'accesso al nodo, // nel corpo del for e' gestito in modo circolare // esempio con 6 nodi: // se si parte dal nodo con indice 2 per effettuare 6 // iterazioni si finirà nel nodo con indice 1 srand( long(time(0)) ); int j = ( (int(lrand48()) % max_bandwidth_) + 1 ); int i = ( int(lrand48()) % nodesNum); for ( i ; i < j; i++ ) { currentNode = nodesVect_[(i % nodesNum)]; if ( bandWidth() != 0 ) { // se il nodo corrente e' in uno stato di sospensione // il metodo Node::send() ritorna un valore NULL // ( e decrementa il contatore // dei cicli di attesa del nodo ) Packet* tosend = currentNode->send(); if( tosend != NULL ) if ( enqueue( tosend ) == true ) cout << "Pacchetto accodato da " << currentNode->getAddress() << ", banda libera: " << bandWidth() << endl; else ;//cout << "Impossibile accodare il pacchetto" << endl; } else { // inizializzo il tempo casuale fra 1 e 5 // per il quale un nodo restera' sospeso nel caso // di banda piena. // storicamente, nelle lan Ethernet il tempo di attesa // nel caso di una collisione e' compreso fra 1 e 16 ms srand48( long(time(0)) + i ); int suspendTime = ( (int(lrand48()) % 5) + 1 ); currentNode->suspend( suspendTime ); } } // una decisione vagamente casuale di quanti pacchetti // recapitare per ogni ciclo di spedizioni j = ( int(lrand48()) % max_bandwidth_ ); for ( int i=0; i < j; i++) deliverPacket(); //cout << "bandWidth: " << bandWidth() << endl; }