本以为The ONE会每隔updateInterval
将TTL(time-to-live)到期的包丢弃,其实不是这样的,而是每隔1分钟丢弃TTL到期的包。本文介绍消息生存时间TTL以及因TTL到期丢包的技术细节,包括dropExpiredMessages
, deleteMessage
。
1. TTL
1.1 单位
消息生存时间TTL默认单位是分,可以通过设置文件将其改其秒,相关源代码如下:
//Message.java /*** TTL单位默认是分 ***/ public static final String TTL_SECONDS_S = "Scenario.ttlSeconds"; private static boolean ttlAsSeconds = false; //TTL单位默认为分 public static final int INFINITE_TTL = -1; //Value for infinite TTL of message public static void reset() { ttlAsSeconds = s.getBoolean(TTL_SECONDS_S, false); //Scenario.ttlSeconds } //可以在设置文件设置消息生成时间TTL,如下: # Message TTL of 300 minutes (5 hours) Group.msgTtl = 300
1.2 默认值
如果在设置文件不设置Group.msgTtl
和Scenario.ttlSeconds
,消息生存时间TTL默认值是infinite
,确切的说是Integer.MAX_VALUE
。相关源代码如下:
/*** 新创建消息的TTL为-1,即消息的TTL为Integer.MAX_VALUE ***/ //Message.java public static final int INFINITE_TTL = -1; public Message(DTNHost from, DTNHost to, String id, int size) { this.initTtl = INFINITE_TTL; } /*** 创建消息,若设置文件没设置Group.msgTtl,则按INFINITE_TTL来 ***/ //MessageRouter.java public boolean createNewMessage(Message m) { m.setTtl(this.msgTtl); m.addToMessages(true); //将消息加入到HashMap<String, Message> messages return true; } //MessageRouter.java,从设置文件读取Group.msgTtl public MessageRouter(Settings s) { this.msgTtl = Message.INFINITE_TTL; //即msgTtl为-1 if (s.contains(MSG_TTL_S)) { //public static final String MSG_TTL_S = "msgTtl"; this.msgTtl = s.getInt(MSG_TTL_S); } }
initTtl
标识着该消息的生存时间是无限的,即一直存在于仿真期间。但当取得该消息的TTL时,返回的是Integer.MAX_VALUE
,源代码如下:
public int getTtl() { if (this.initTtl == INFINITE_TTL) { //默认的情况,没设置Group.msgTtl和Scenario.ttlSeconds return Integer.MAX_VALUE; } else { if (ttlAsSeconds) { //TTL单位是秒,通过Scenario.ttlSeconds=true设置 return (int)(this.initTtl - (SimClock.getTime()-this.timeCreated) ); } else { //TTL单位是分 return (int)( ((this.initTtl * 60) - (SimClock.getTime()-this.timeCreated)) /60.0 ); } } }
2. 丢包drop
2.1 何时丢包
The ONE丢包有两种情况:其一,TTL到期;其二,缓冲区满了。这点只考虑TTL到期丢包的情况。最开始,以为每个updateInterval
都会将那些TTL到期的包丢弃,看了源代码才发现,其实不是这样的,而是1分钟或60秒。相关源代码如下:
//ActiveRouter.java public void update() { ... /*** 丢弃那些TTL到期的数据包(每隔ttlCheckInterval检查一次) ***/ if (SimClock.getTime() - lastTtlCheck >= ttlCheckInterval && sendingConnections.size() == 0) { dropExpiredMessages(); lastTtlCheck = SimClock.getTime(); } ... } //关于ttlCheckInterval private static int ttlCheckInterval = 60; public ActiveRouter(Settings s) { ... ttlCheckInterval = (new Settings().getBoolean(Message.TTL_SECONDS_S, false) ? 1 : 60); }
值得注意的是:只有在节点没有发送数据的时候(sendingConnections
的size为0),才会丢包。简单防止正在传输的消息被删除。
2.2 dropExpiredMessages
dropExpiredMessages删除TTL到期的消息,源代码如下:
//ActiveRouter.java protected void dropExpiredMessages() { Message[] messages = getMessageCollection().toArray(new Message[0]); for (int i=0; i<messages.length; i++) { int ttl = messages[i].getTtl(); if (ttl <= 0) { deleteMessage(messages[i].getId(), true); //deleteMessage(String id, boolean drop) } } }
2.3 deleteMessage
deleteMessage
从消息缓冲区删除指定消息,并更多相关reports
,源代码如下:
//MessageRouter.java public void deleteMessage(String id, boolean drop) { Message removed = removeFromMessages(id); if (removed == null) throw new SimError("no message for id " + id + " to remove at " + this.host); for (MessageListener ml : this.mListeners) { //消息监听器通知更新reports相关内容 ml.messageDeleted(removed, this.host, drop); } }赞赏
微信赞赏
支付宝赞赏
对于Epidemic、SAW等算法在TheONE中当缓存满的时候怎么处理?随机删除吗?
好问题,一时记不起来是用什么策略删除了,建议你查看源代码。
请问 Scenario.ttlSeconds=true设置在哪里?
Scenario.ttlSeconds=true
直接放在设置文件(*_settings.txt
)就可以了。Pingback: The ONE使用笔记:DirectDelivery路由 | | Spark & Shine