⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 network.c

📁 比较权威的p2p仿真软件
💻 C
字号:
/* * Copyright (c) 2003-2005 Thomer M. Gil (thomer@csail.mit.edu), *                    Robert Morris (rtm@csail.mit.edu). *                    Massachusetts Institute of Technology *  * Permission is hereby granted, free of charge, to any person obtaining * a copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including * without limitation the rights to use, copy, modify, merge, publish, * distribute, sublicense, and/or sell copies of the Software, and to * permit persons to whom the Software is furnished to do so, subject to * the following conditions: *  * The above copyright notice and this permission notice shall be * included in all copies or substantial portions of the Software. *  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */#include "network.h"#include "events/netevent.h"#include "failuremodels/failuremodelfactory.h"#include <cmath>#include <iostream>#include <cassert>using namespace std;Network *Network::_instance = 0;Network*Network::Instance(Topology *top, FailureModel *fm){  if(!_instance)    _instance = New Network(top, fm);  return _instance;}Network::Network(Topology *top, FailureModel *fm) : _top(0),  _nodechan(0){  _nodechan = chancreate(sizeof(Node*), 0);  assert(_nodechan);  _top = top;  assert(_top);  _failure_model = fm;  assert(_failure_model);  _all_ips = New vector<IPAddress>;  assert(_all_ips);  _all_nodes = New set<Node*>;  assert(_all_nodes);  _highest_ip = 0;  _changed = false;  // get the nodes  thread();}Network::~Network(){  for(HashMap<IPAddress, Node*>::const_iterator p = _nodes.begin(); p != _nodes.end(); ++p)    delete p.value();  chanfree(_nodechan);  delete _top;  delete _failure_model;  delete _all_ips;  delete _all_nodes;}const set<Node*> *Network::getallnodes(){  // copy only non-mapped IP address  if(!_all_nodes->size())    for(HashMap<IPAddress, Node*>::const_iterator p = _nodes.begin(); p != _nodes.end(); ++p)      _all_nodes->insert(p.value());  return _all_nodes;}vector<IPAddress> *Network::getallfirstips(){  if(!_all_ips->size())    for(HashMap<IPAddress, Node*>::const_iterator p = _nodes.begin(); p != _nodes.end(); ++p) {      _all_ips->push_back(p.key());    }  _changed = false;  return _all_ips;}TimeNetwork::avglatency(){  static Time answer = 0;  Time total_latency = 0;  unsigned n = 0;  if(answer)    return answer;  if(_nodes.size() == 0 || _nodes.size() == 1)    return (answer = 0);  for(HashMap<IPAddress, Node*>::const_iterator p = _nodes.begin(); p != _nodes.end(); ++p) {    for(HashMap<IPAddress, Node*>::const_iterator q = _nodes.begin(); q != _nodes.end(); ++q) {      if(p.key() == q.key())        continue;      total_latency += _top->latency(p.key(), q.key(), true);      total_latency += _top->latency(p.key(), q.key(), false);      n += 2;    }  }  return (answer = (total_latency / n));}// // taken from http://www-math.mit.edu/~spielman/ECC/randGen.c, which notes the// source as the book "Numerical Recipies in C".// floatNetwork::gaussian(double variance){  float fac,rsq,v1,v2;  if(variance == 0)    return 0.0;  do {    v1=2.0*(random()/(RAND_MAX*1.0))-1.0;    v2=2.0*(random()/(RAND_MAX*1.0))-1.0;    rsq = v1*v1 + v2*v2;  } while (rsq >= 1.0 || rsq == 0.0);  fac = sqrt(-2.0*log(rsq)/rsq);  return (v2*fac) * (variance);}IPAddressNetwork::unused_ip(){  return ++_highest_ip;}// Protocols should call send() to send a packet into the network.voidNetwork::send(Packet *p){  extern bool with_failure_model;  Node *dst = getnode(p->dst());  Node *src = getnode(p->src());  assert (dst);  assert (src);  Time latency = _top->latency(src->ip(), dst->ip(), p->reply());  if (src->ip () != dst->ip ())    latency += p->_queue_delay;  //  // if the packet was still ok, see if it accidentally disappears due to  // lossrate.  //  // if the node was dead or the packet got lost, we have to delay the packet a  // bit. (p->ok is set on the receiving side, so if it's false, this must be a  // reply. punish the packet by delaying it according to the failure model.)  //  // if timeout value was passed to doRPC(), then doRPC has to return  // [timeout]ms after it was started.  make sure we return by then.  //  // if timeout == 0, then let the failure model ADD some punishment.  //  if(p->ok() && _top->lossrate()) {    unsigned random_number = (unsigned) ((random() % 10000));    p->_ok = _top->lossrate() <= random_number ? true: false;  }  if(!p->ok()) {    if(p->timeout()) {      int tmplat = p->timeout() - _top->latency(dst->ip(), src->ip(), false);      latency = tmplat <= 0 ? 0 : (unsigned) tmplat;    } else if(with_failure_model) {      latency += _failure_model->failure_latency(p);    }  }  NetEvent *ne = New NetEvent();  assert(ne);  Time tmplat = (Time) (latency + 			gaussian(latency*(_top->noise_variance()/100.0)));  ne->ts = now() + tmplat;  ne->ip = p->dst();  ne->p = p;  EventQueue::Instance()->add_event(ne);}voidNetwork::map_ip(IPAddress firstx, IPAddress newx){  assert(!_new2old.find_pair(newx));  _new2old.insert(newx, firstx);}IPAddressNetwork::first_ip(IPAddress newx){  if(_new2old.find_pair(newx))    return _new2old[newx];  assert(newx <= _nodes.size());  return newx;}voidNetwork::run(){  Alt a[3];  Node *node;  a[0].c = _nodechan;  a[0].v = &node;  a[0].op = CHANRCV;  a[1].op = CHANEND;    while(1) {    int i;    if((i = alt(a)) < 0) {      cerr << "interrupted" << endl;      continue;    }    switch(i) {      // register node on network      case 0:        if(_nodes[node->ip()]) {          cout << "warning: node " << node->ip() << " already exists" << endl;          _nodes.remove(node->ip());        }        _nodes.insert(node->ip(), node);        if(node->ip() > _highest_ip)          _highest_ip = node->ip();        _changed = true;        break;      default:        break;    }  }}#include "bighashmap.cc"

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -