3月27日学习总结

一、英语学习

1、【每日一句英语】

If you look the right way, you can see that the whole world is a garden.

如果欣赏的角度对了,整个世界都是花园。

2、阅读BBC新闻

 词汇积累

a sore throat嗓子疼
blocked nose鼻塞
soldier on坚持干活
perk somebody up使某人精神振作
duvet day休假日
sniffle流鼻涕,吸鼻子
at death’s door病入膏肓
sickie假病假,称病缺勤
migraine偏头疼
common cold感冒
symptom症状
germ病菌
catch a cold患感冒
recuperate恢复,康复
under the weather生病
cure治疗方法
lurgy小病
not to be sneezed at不可轻视的

二、ONE仿真平台学习

今天主要学习了DirectDelivery路由,首先,该路由继承了父类ActiveRouter,所以顺带了解了ActiveRouter类的代码结构,以下是今天学习的总结:

2.1 DirectDeliveryRouter代码:

package routing;

import core.Settings;

/**
 * Router that will deliver messages only to the final recipient.
 */
public class DirectDeliveryRouter extends ActiveRouter {

	public DirectDeliveryRouter(Settings s) {
		super(s);
	}
	
	protected DirectDeliveryRouter(DirectDeliveryRouter r) {
		super(r);
	}
	
	@Override
	public void update() {
		super.update();
        //判断能否进行传输
		if (isTransferring() || !canStartTransfer()) {	
			return; // can't start a new transfer
		}
		
		// Try only the messages that can be delivered to final recipient 
        //只尝试可以传递给最终目的节点
        //若有目的节点就在本节点或者邻居节点的消息
		if (exchangeDeliverableMessages() != null) { 
			return; // started a transfer
		}
	}
	
	@Override
	public DirectDeliveryRouter replicate() {
		return new DirectDeliveryRouter(this);
	}
}

   DirectDelivery路由策略很简单,每个节点携带自创建的消息,不断移动,直到遇到目的节点,才把消息传递出去,整个通信过程从不借助其他节点。这点方法优点很明显,开销是最低的,但缺点也很明显,效率是最低的。这里要学习三个函数,分别是:isTransferring()canStartTransfer()exchangeDeliverableMessages()

  2.2 ActiveRouter主要做5件事,其源码如下:

@Override
	public void update() {	
		//调用MessageRouter的update()
		super.update();
		
		/* in theory we can have multiple sending connections even though
		  currently all routers allow only one concurrent sending connection
		  理论上,我们可以有多个发送连接,尽管目前所有路由器都只允许一个并发发送连接
		   */
		for (int i=0; i<this.sendingConnections.size(); ) {
			boolean removeCurrent = false;
			Connection con = sendingConnections.get(i);
			
			/* finalize ready transfers 1. 处理已完成传输的数据包 */
			if (con.isMessageTransferred()) {
				if (con.getMessage() != null) {
					transferDone(con);
					con.finalizeTransfer();
				} /* else: some other entity aborted transfer */
				removeCurrent = true;
			}
			/* remove connections that have gone down 2. 中止那些断开链路上的数据包 */
			else if (!con.isUp()) {
				if (con.getMessage() != null) {
					transferAborted(con);
					con.abortTransfer();
				}
				removeCurrent = true;
			} 
//			3. 必要时,删除那些最早接收到且不正在传输的消息
			if (removeCurrent) {
				// if the message being sent was holding excess buffer, free it
				if (this.getFreeBufferSize() < 0) {
					this.makeRoomForMessage(0);
				}
				sendingConnections.remove(i);
			}
			else {
				/* index increase needed only if nothing was removed */
				i++;
			}
		}
		
		/* time to do a TTL check and drop old messages? Only if not sending 4. 丢弃那些TTL到期的数据包(只在没有消息发送的情况) */
		if (SimClock.getTime() - lastTtlCheck >= TTL_CHECK_INTERVAL && 
				sendingConnections.size() == 0) {
			dropExpiredMessages();
			lastTtlCheck = SimClock.getTime();
		}
		 /* 5. 更新能量模板 */
		if (energy != null) {
			/* TODO: add support for other interfaces */
			NetworkInterface iface = getHost().getInterface(1);
			energy.update(iface, getHost().getComBus());
		}
	}

由上可见,ActiveRouter.update主要做以下5件事:

  • 处理已完成传输的数据包
  • 中止那些断开链路上的数据包
  • 必要时,删除那些最早接收到且不正在传输的消息
  • 丢弃那些TTL到期的数据包(只在没有消息发送的情况)
  • 更新能量模板

2.3 isTransferring()和canStartTransfer()

判断该节点能否进行传输消息,存在以下情况一种以上的,直接返回,不更新:

  • 本节点正在传输,sendingConnections.size() > 0
  • 没有邻居节点,即没有节点与之建立连接,connections.size() == 0
  • 有邻居节点,但有链路正在传输(想想无线信道),!con.isReadyForTransfer()
  • 缓冲区没有消息,this.getNrofMessages() == 0

2.3.1 isTransferring()

isTransferring()函数覆盖了以上前三种情况,其源代码如下:

/**
	 * Returns true if this router is transferring something at the moment or
	 * some transfer has not been finalized.
	 * @return true if this router is transferring something
	 * 判断该节点能否进行传输消息
	 * 
	 */
	public boolean isTransferring() {
		 //情形1:本节点正在传输
		if (this.sendingConnections.size() > 0) {
			return true; // sending something
		}
		
		List<Connection> connections = getConnections();
		//情型2:没有邻居节点
		if (connections.size() == 0) {
			return false; // not connected
		}
		
		//情型3:有邻居节点,但有链路正在传输
//		只有当与邻居相连的所有链路都是空闲的,才能传输
		for (int i=0, n=connections.size(); i<n; i++) {
			Connection con = connections.get(i);
			if (!con.isReadyForTransfer()) {
//				一条链路能用于传输需要同时满足两个条件:其一,该链路是建立的;其二,该链路是空闲的。
				return true;	// a connection isn't ready for new transfer
			}
		}
		
		return false;		
	}

值得注意的是,只有当与邻居相连的所有链路都是空闲的,才能传输,这是因为无线的传输介质是广播的。而且每次传输只能有一个connection进行传输,可见The ONE仿真了无线信道,但其他没法收到这个广播包。

 判断链路是否空闲

The ONE的链路用Connection类表示,一条链路能用于传输需要同时满足两个条件:其一,该链路是建立的;其二,该链路是空闲的。相关成员变量如下:

//Connection.java
 private boolean isUp;       //连接是否建立
 protected Message msgOnFly; //连接是否被占用


public boolean isReadyForTransfer() {
		return this.isUp && this.msgOnFly == null; 
	}

2.3.2 canStartTransfer()

canStartTransfer判断该节点能否开始传输,缓冲区有消息,并且有邻居节点,才返回真。源代码如下:

/**
	 * Makes rudimentary checks (that we have at least one message and one
	 * connection) about can this router start transfer.
	 * @return True if router can start transfer, false if not
	 * 判断该节点能否开始传输,缓冲区有消息,并且有邻居节点,才返回真。
	 */
	protected boolean canStartTransfer() {
		if (this.getNrofMessages() == 0) {//缓冲区空
			return false;
		}
		if (this.getConnections().size() == 0) {//没有连接建立,即没有邻居节点
			return false;
		}
		//不符合上述两个情况 返回真 即可以开始传输
		return true;
	}

2.4 exchangeDeliverableMessages()

exchangeDeliverableMessages用于交换该节点与邻居节点间的消息,这些消息的目的节点是该节点或者其邻居节点。值得注意的是:该节点可能会有多个邻居节点(The ONE表示为多个connection),但只能让一个connection传输数据,想想无线信道。所以,只有有一个消息能传输到目的节点,就返回。exchangeDeliverableMessages先看本节点是否有消息的某个邻居节点,如果没有,再查看邻居节点是否有消息的目的节点是本节点。其源代码如下:

/**
	 * Exchanges deliverable (to final recipient) messages between this host
	 * and all hosts this host is currently connected to. First all messages
	 * from this host are checked and then all other hosts are asked for
	 * messages to this host. If a transfer is started, the search ends.
	 * @return A connection that started a transfer or null if no transfer
	 * was started
	 * 用于交换该节点与邻居节点间的消息,这些消息的目的节点是该节点或者其邻居节点。
	 * 值得注意的是:该节点可能会有多个邻居节点(The ONE表示为多个connection),
	 * 但只能让一个connection传输数据,想想无线信道。所以,只有有一个消息能传输到目的节点,就返回。
	 * 
	 * exchangeDeliverableMessages先看本节点是否有消息的某个邻居节点,如果没有,再查看邻居节点是否有消息的目的节点是本节点。
	 */
	protected Connection exchangeDeliverableMessages() {
		List<Connection> connections = getConnections();

		if (connections.size() == 0) {
			return null;
		}
		
	    //getMessagesForConnected()返回那些目的节点就是邻居节点的消息
	    //tryMessagesForConnected,尝试将上述返回的消息发送到目的节点(值得注意的是:只能发一个)
		@SuppressWarnings(value = "unchecked")
		Tuple<Message, Connection> t =
			tryMessagesForConnected(sortByQueueMode(getMessagesForConnected()));

		if (t != null) {
			return t.getValue(); // started transfer
		}
		
		// didn't start transfer to any node -> ask messages from connected
//		如果没发送成功,看邻居节点的缓冲区是否有消息的目的节点是该节点,若是,尝试传输
		for (Connection con : connections) {
			if (con.getOtherNode(getHost()).requestDeliverableMessages(con)) {
				return con;
			}
		}
		
		return null;
	}

2.4.1 getMessagesForConnected()

getMessagesForConnected返回本节点缓冲区的那些目的节点在其邻居节点的消息,这些消息只要投递成功,就成功达到目的节点。源代码如下:

//返回那些消息的目的节点是某个邻居节点
	protected List<Tuple<Message, Connection>> getMessagesForConnected() {
		if (getNrofMessages() == 0 || getConnections().size() == 0) {
			/* no messages -> empty list */
			return new ArrayList<Tuple<Message, Connection>>(0); 
		}

		List<Tuple<Message, Connection>> forTuples = 
			new ArrayList<Tuple<Message, Connection>>();
		for (Message m : getMessageCollection()) {	//遍历缓冲区每个消息
			for (Connection con : getConnections()) {	//遍历每个邻居节点
				DTNHost to = con.getOtherNode(getHost());
				if (m.getTo() == to) {	//消息的目的节点是邻居节点
					forTuples.add(new Tuple<Message, Connection>(m,con));
				}
			}
		}
		
		return forTuples;
	}

2.4.2 tryMessagesForConnected()

tryMessagesForConnected尝试着将消息传输出去,只要有一个成功(意味着该信道被占用),就返回。

2.4.3 requestDeliverableMessages()

requestDeliverableMessages如果本节点没有消息的目的节点是邻居节点,那么看看邻居节点是否有消息的目的节点在本节点。DTNHostrequestDeliverableMessages调用ActiveRouterrequestDeliverableMessages。源代码如下:

//	requestDeliverableMessages如果本节点没有消息的目的节点是邻居节点,
//	那么看看邻居节点是否有消息的目的节点在本节点。
	@Override
	public boolean requestDeliverableMessages(Connection con) {
		if (isTransferring()) {
			return false;
		}
		
		DTNHost other = con.getOtherNode(getHost());	//即得到本节点
		/* do a copy to avoid concurrent modification exceptions 进行复制以避免并发修改异常
		 * (startTransfer may remove messages) */
		ArrayList<Message> temp = 
			new ArrayList<Message>(this.getMessageCollection());
		for (Message m : temp) {
			if (other == m.getTo()) {
				if (startTransfer(m, con) == RCV_OK) {
					return true;
				}
			}
		}
		return false;
	}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值