ns2代码分析(一)-数据包指针进入队列

   我发现一个现象,也就在中国,会有某某代码分析,某某代码走读。国外似乎就没有这种现象。

   没有法子,想在ns2上做点自己东西,不添加C++代码估计是办不到的。之前我分析了quic中一个小仿真器的大致原理[1]。switch对象中的队列长度为什么增长?进的数据包多,而发送数据包少。就是交换机对象的发送队列在每次发包的之后会检测,上次发送数据包需要耗费的时间,就是网卡的处理能力(packet_length/bandwidth)。我上传的quic_simulator[1],queue.cc在收到一个数据包,文件中有这样一行代码Schedule(clock_->Now()+tx_port_->TimeUntilAvailable());就是经过上次数据包处理延时,本次数据包才能进入网卡,发送到链路上Queue::Act(){tx_port_->AcceptPacket(...)}。

   quic仿真器是这样的工作原理,ns2也不例外。

    仿真数据包传递流程,node->queue->delaylink。  ns2仿真链路上的队列ns-2.35\queue\queue.cc接收数据包函数

void Queue::recv(Packet* p, Handler*)
{
	double now = Scheduler::instance().clock();
	enque(p);
	if (!blocked_) {
		/*
		 * We're not blocked.  Get a packet and send it on.
		 * We perform an extra check because the queue
		 * might drop the packet even if it was
		 * previously empty!  (e.g., RED can do this.)
		 */
		p = deque();
		if (p != 0) {
			utilUpdate(last_change_, now, blocked_);
			last_change_ = now;
			blocked_ = 1;
			target_->recv(p, &qh_);
		}
	}
}
    第一次接收到数据包,enque(p)将数据包加入队列,之后p = deque()将数据包弹出队列,blocked_ = 1设置为阻塞,target_->recv(p, &qh_);将数据包发送到延时链路上,同时这个函数传递个一个队列句柄指针qh_。

ns-2.35\link\delay.cc

void LinkDelay::recv(Packet* p, Handler* h)
{
	double txt = txtime(p);
	Scheduler& s = Scheduler::instance();
	if (dynamic_) {
		Event* e = (Event*)p;
		e->time_= txt + delay_;
		itq_->enque(p); // for convinience, use a queue to store packets in transit
		s.schedule(this, p, txt + delay_);
	} else if (avoidReordering_) {
		// code from Andrei Gurtov, to prevent reordering on
		//   bandwidth or delay changes
 		double now_ = Scheduler::instance().clock();
 		if (txt + delay_ < latest_time_ - now_ && latest_time_ > 0) {
 			latest_time_+=txt;
 			s.schedule(target_, p, latest_time_ - now_ );
 		} else {
 			latest_time_ = now_ + txt + delay_;
 			s.schedule(target_, p, txt + delay_);
 		}

	} else {
		s.schedule(target_, p, txt + delay_);
	}
	s.schedule(h, &intr_, txt);
}

    数据包进入链路后,链路会计算数据在网卡上的发送时间。在recv函数中,将数据包的网卡处理时延和这个句柄注册到scheduler(s.schedule(h, &intr_, txt);)。

    这个时刻到来,调度器回调队列句柄,进行出队操作。ns-2.35\queue\queue.cc:

void QueueHandler::handle(Event*)
{
	queue_.resume();
}

void Queue::resume()
{
	double now = Scheduler::instance().clock();
	Packet* p = deque();
	if (p != 0) {
		target_->recv(p, &qh_);
	} else {
		if (unblock_on_resume_) {
			utilUpdate(last_change_, now, blocked_);
			last_change_ = now;
			blocked_ = 0;
		}
		else {
			utilUpdate(last_change_, now, blocked_);
			last_change_ = now;
			blocked_ = 1;
		}
	}
}

  如果在这个网卡处理时延之间有数据包到来,就到进队等待,队列长度就会增加。

[1]谷歌quic协议自带网络仿真器代码分析(一)

[2]NS 发送一个 cbr 数据包的过程

  • 3
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值