peersim
选择 Run—> Run Configuration
双击Java Application,会出现New_configuration的界面
在右侧的“Main” 面板中设置main class为peersim.Simulator:
然后点击“Argument”面板,设置 “Program arguments” 为 config-example1.txt 所在的位置,注意要加双引号:
最后运行即可,得到的结果和在cmd上运行一样
Chord等协议的模拟:
a. 需要从官方网站http://sourceforge.net/projects/chord/?source=dlp上下载对应的Chord和Pastry协议的压缩包
b. 解压
c. 将chord源码生成.jar,命名为chord.jar,放在chord目录下
d. 从peersim-1.0.5.jar中将peersim-1.0.5、jar:jep-2.3.0.jar、djep-1.0.0.jar三个包拷到chord目录下
e. 运行java -cp "peersim-1.0.5.jar:jep-2.3.0.jar:djep-1.0.0.jar;chord.jar" peersim.Simulator example.cfg 即可看到模拟结果
第c步需要打包的原因:
Chord目录下提供的readMe-chord.pdf是不需要对chord源码打包,但是这样做的话是会报NoDefClassFound错误的,因为Chord源码本没有编译过,没有.class文件。
Pastry类似。
首先要说下所谓的配置文件,其实就是一个txt文件,语法也是非常简单,类似java里的给类里的变量赋值,这也正对应了配置文件的作用,配置文件,当然就是为实验的参数进行配置用的,所以配置文件的主要功能就是配置各类参数,定义一些协议类、控制类、初始化类以及一些常数。
1 # PEERSIM EXAMPLE 1 #配置文件中#是注释符 2 3 random.seed 1234567890 #随机数种子 4 simulation.cycles 30 #这里设置了模拟的周期为30,类似java里给变量赋值 语法就是aa.bb cc ,把aa的bb赋cc的值 很容易理解 5 6 control.shf Shuffle #shuffle就是洗牌的意思,control类通常用来修改或者跟踪仿真过程的,这里洗牌的意思就是在每个周期,把节点打乱顺序 7 8 network.size 50000 #设置网络的大小为50000 9 10 protocol.lnk IdleProtocol #这里开始,就要注意下了,出现了语法, 定义了一个叫做lnk的协议,这个协议的值为 IdleProtocol,这似乎是一个很常见的协议,目前我的理解就 #是他可以为提供其他协议提供邻居的信息 11 12 protocol.avg example.aggregation.AverageFunction # 这里同样,定义了叫做avg的协议,值是后面的一长串,后面协议的功能一会会提到,主要就是求平均数 13 protocol.avg.linkable lnk # 注意下,这行的意思是说avg(在上一行定义的)里有一个属性是linkable,为这个属性赋值,值为之前定义的lnk,之前 #就是因为有的地方是自定义的名称,有的是定义好的属性,所以分不清,具体可以多看看源代码 14 15 init.rnd WireKOut #这里定义了一个叫rnd的初始器,目前我理解的作用是定义网络拓扑结构,下面的k=20,意思是以20的出度和其他节点连接 16 init.rnd.protocol lnk #rnd的protocol属性设为lnk 17 init.rnd.k 20 18 19 init.peak example.aggregation.PeakDistributionInitializer#这里定义的也是有关设置初始化的,但是不是拓扑结构,是分布,我理解的就是50000个节点,怎么给他们赋初值 20 init.peak.value 10000 #这种peak赋初值的方法是这么做的,第一个节点的值设为value,这里也就是10000,其他全是0 21 init.peak.protocol avg #同样需要为peak的protocol属性设值,这里要用avg而不用lnk,因为avg的protocol属性已经为lnk了 22 23 init.lin LinearDistribution #这是和peak相似功能的另一种初始化方法,名字就能看出来,是线性增长的方法,可以为他设最小和最大值 24 init.lin.protocol avg 25 init.lin.max 100 26 init.lin.min 0 27 28 # you can change this to select the peak initializer instead 29 include.init rnd peak #这里说下,include后面出现的才是真正会使用的,这里我把原来的lnk改为peak,因为peak更好理解一点,所 #以这次实验,跟lin就无关了,如果改为include.init rnd lin 同样就用不到peak了 30 31 control.avgo example.aggregation.AverageObserver #这里最后设值了一个control量,用来监测仿真过程,下面会详细分析 32 control.avgo.protocol avg
代码部分到此,接着我把实验结果贴出来,再仔细分析
F:\peersim-1.0.5>java -cp peersim-1.0.5.jar;jep-2.3.0.jar;djep-1.0.0.jar peersim.Simulator example/config-example1.txt
Simulator: loading configuration
ConfigProperties: File example/config-example1.txt loaded.
Simulator: starting experiment 0 invoking peersim.cdsim.CDSimulator
Random seed: 1234567890
CDSimulator: resetting
Network: no node defined, using GeneralNode
CDSimulator: running initializers
- Running initializer init.rnd: class peersim.dynamics.WireKOut
- Running initializer init.peak: class example.aggregation.PeakDistributionInitializer
CDSimulator: loaded controls [control.avgo, control.shf]
CDSimulator: starting simulation
control.avgo: 0 0.0 10000.0 50000 0.2 2000.0 49999 1
CDSimulator: cycle 0 done
control.avgo: 1 0.0 5000.0 50000 0.2 687.4737494749895 49996 1
CDSimulator: cycle 1 done
control.avgo: 2 0.0 2500.0 50000 0.2 245.57038015760315 49980 1
CDSimulator: cycle 2 done
control.avgo: 3 0.0 1250.0 50000 0.2 83.07127865884954 49918 1
CDSimulator: cycle 3 done
control.avgo: 4 0.0 625.0 50000 0.2 27.385730697893184 49571 1
CDSimulator: cycle 4 done
control.avgo: 5 0.0 156.25 50000 0.2 7.57358497068821 47829 5
CDSimulator: cycle 5 done
control.avgo: 6 0.0 78.125 50000 0.2 2.2637719903529367 39984 2
CDSimulator: cycle 6 done
control.avgo: 7 0.0 29.363781213760376 50000 0.2 0.6944917092712494 18436 2
CDSimulator: cycle 7 done
control.avgo: 8 0.0 14.692321419715881 50000 0.2 0.22599995660240516 1676 1
CDSimulator: cycle 8 done
control.avgo: 9 0.0 7.773749530315399 50000 0.19999999999999996 0.07499273060350721 8 2
CDSimulator: cycle 9 done
control.avgo: 10 0.007466878741979599 3.9366912096738815 50000 0.19999999999999699 0.023950746235829403 1 1
CDSimulator: cycle 10 done
control.avgo: 11 0.037196914490778 2.003569261432858 50000 0.19999999999999693 0.007786713762873151 1 1
CDSimulator: cycle 11 done
control.avgo: 12 0.07241240396638204 1.439594765546559 50000 0.20000000000000212 0.002526494751788285 1 1
CDSimulator: cycle 12 done
control.avgo: 13 0.11444778778013642 0.8058056706961025 50000 0.19999999999999968 8.047749060418319E-4 1 1
CDSimulator: cycle 13 done
control.avgo: 14 0.14527491199664566 0.5412341546913619 50000 0.19999999999999857 2.5669976815967627E-4 1 1
CDSimulator: cycle 14 done
control.avgo: 15 0.16625072097394172 0.3086751814077813 50000 0.1999999999999984 8.071849333870349E-5 1 1
CDSimulator: cycle 15 done
control.avgo: 16 0.17188874045468727 0.25586305250877606 50000 0.19999999999999915 2.56414324360324E-5 1 1
CDSimulator: cycle 16 done
control.avgo: 17 0.18126059597579963 0.2284452071697809 50000 0.19999999999999926 8.156374000530416E-6 1 2
CDSimulator: cycle 17 done
control.avgo: 18 0.1908732136140849 0.2164359304896662 50000 0.20000000000000073 2.596046179086563E-6 1 2
CDSimulator: cycle 18 done
control.avgo: 19 0.19463901353170004 0.20867151463200723 50000 0.20000000000000132 8.247630624269391E-7 1 1
CDSimulator: cycle 19 done
control.avgo: 20 0.19743621150008228 0.20414677686379626 50000 0.19999999999999932 2.598124738924983E-7 1 1
CDSimulator: cycle 20 done
control.avgo: 21 0.19853546091585267 0.20213994106099414 50000 0.20000000000000218 8.305109997981584E-8 2 1
CDSimulator: cycle 21 done
control.avgo: 22 0.19914334355323826 0.20111512260564823 50000 0.19999999999999982 2.6420408323917597E-8 1 1
CDSimulator: cycle 22 done
control.avgo: 23 0.1994687670844077 0.20059480913650848 50000 0.20000000000000076 8.351299478222964E-9 2 1
CDSimulator: cycle 23 done
control.avgo: 24 0.19973746582822932 0.20030291389208998 50000 0.19999999999999854 2.676425576105711E-9 1 2
CDSimulator: cycle 24 done
control.avgo: 25 0.19983215529336568 0.20018999494961187 50000 0.19999999999999687 8.676425051288862E-10 1 1
CDSimulator: cycle 25 done
control.avgo: 26 0.19989827974265328 0.20010713659190948 50000 0.19999999999999804 2.7427770854287373E-10 1 1
CDSimulator: cycle 26 done
control.avgo: 27 0.19992737138288125 0.2000588315827033 50000 0.1999999999999992 8.762195519908992E-11 1 1
CDSimulator: cycle 27 done
control.avgo: 28 0.1999626822953865 0.200032897978195 50000 0.19999999999999915 2.7973829010656408E-11 2 1
CDSimulator: cycle 28 done
control.avgo: 29 0.19997940109815665 0.20001754407497246 50000 0.2000000000000003 8.765247306483662E-12 1 2
CDSimulator: cycle 29 done
这就是之前配置文件的实验结果,当时我第一反应是这每一列是对应的什么东西?在哪里定义的?可惜在网上没有找到,所以就自己一点点开始找。
开始我在AverageObserver文件里找(所有这些文件都可以在peer的src文件夹里找到),里面并没有直接定义这些结果的表示,不过已经有了
System.out.println(name + ": " + time + " " + is);这行,至少我明白了第一列的control.avgo对于的是name属性,0-29的序列对于的是time(为什么是time我还没仔细看),后面的几列对应的is,is就是IncrementalStats类的实例,
接着我又去这个 IncrementalStats文件里找,发现了这个方法
public String toString() {
return min+" "+max+" "+n+" "+sum/n+" "+getVar()+" "+
countmin+" "+countmax;
}
这下每列对于的什么就很清楚了,分别是网络中的最小值,最大值,网络节点数,平均数,方法和最小最大值记数。
接着我开始分析数据内容,主要关注第3和第4列,也就是最小值最大值,开始从0和10000开始,正好对于之前我设置的peak的初始化器,接着通过求平均数的方法,最大值变为(0+10000)/2=5000,一次类推,每个周期的最大值一直变为一半。
到这里我大概明白了实验的功能,但是流程还不清楚,我回去看AverageObserver文件,里面核心是这个函数
public boolean execute() {
long time = peersim.core.CommonState.getTime();
IncrementalStats is = new IncrementalStats();
for (int i = 0; i < Network.size(); i++) {
SingleValue protocol = (SingleValue) Network.get(i)
.getProtocol(pid);
is.add(protocol.getValue());
}
/* Printing statistics */
System.out.println(name + ": " + time + " " + is);
/* Terminate if accuracy target is reached */
return (is.getStD() <= accuracy);
}
其中is我已经明白了结构,但是这个add()函数到底传进了去什么值,在singleValueHolder里可以查到这个getValue的方法,对于到他的子类example.aggregation.AverageFunction里的方法
public void nextCycle(Node node, int protocolID) {
int linkableID = FastConfig.getLinkable(protocolID);
Linkable linkable = (Linkable) node.getProtocol(linkableID);
if (linkable.degree() > 0) {
Node peer = linkable.getNeighbor(CommonState.r.nextInt(linkable
.degree()));
// Failure handling
if (!peer.isUp())
return;
AverageFunction neighbor = (AverageFunction) peer
.getProtocol(protocolID);
double mean = (this.value + neighbor.value) / 2;
this.value = mean;
neighbor.value = mean;
}
}
里面的value就是本节点和邻居节点的平均值,所以最后传进is的正是这个平均值。
而is里通过这个方法求出了最终的展示的结果
public final void add( double item ) { add(item,1); }
// --------------------------------------------------------------------
/** Updates the statistics assuming element <code>item</code> is added
* <code>k</code> times.*/
public void add( double item, int k ) {
if( item < min )
{
min = item;
countmin = 0;
}
if( item == min ) countmin+=k;
if( item > max )
{
max = item;
countmax = 0;
}
if(item == max) countmax+=k;
n+=k;
if( k == 1 )
{
sum += item;
sqrsum += item*item;
}
else
{
sum += item*k;
sqrsum += item*item*k;
}
}
到此为止,配置文件以及结果的含义,整个流程大概就明白了,还有一些关于配置文件里ID的部分,看看上面提的文件里的构造函数就能明白了。
昨天学习了peersim的cycle模式,今天开始继续悟事件模式。
总的来说,我个人认为事件模式是周期模式的升级版,或者说,周期模式只是事件模式的一个子功能。
事件模式是基于时间和事件的(没打错),每次实验的开始会设定结束时间和若干要处理的事件,当时间结束,或者事件全部做完,实验就结束,而在结束之前,也是可以周期性的执行一些事件,所以说周期模式只是事件模式的一个子功能。
学习方法还是直接看代码,看不懂的地方直接去找对应的源文件,一层层从子类往上看。
贴上样例代码,功能和周期模式一样,首先是对网络中的每个节点赋初始值(这里使用线性分布),接着每个节点和相邻节点求平均值
样例代码:
1 /* 2 * Copyright (c) 2003 The BISON Project 3 * 4 * This program is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU Lesser General Public License version 2 as 6 * published by the Free Software Foundation. 7 * 8 * This program is distributed in the hope that it will be useful, 9 * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 * GNU Lesser General Public License for more details. 12 * 13 * You should have received a copy of the GNU Lesser General Public License 14 * along with this program; if not, write to the Free Software 15 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 16 * 17 */ 18 19 package example.edaggregation; 20 21 import peersim.vector.SingleValueHolder; 22 import peersim.config.*; 23 import peersim.core.*; 24 import peersim.transport.Transport; 25 import peersim.cdsim.CDProtocol; 26 import peersim.edsim.EDProtocol; 27 28 /** 29 * Event driven version of epidemic averaging. 30 */ 31 public class AverageED extends SingleValueHolder 32 implements CDProtocol, EDProtocol { //这里除了ED协议,还实现了CD协议,正是因为在实验中会周期性的执行一些事件,所以要实现CD协议 33 34 //-------------------------------------------------------------------------- 35 // Initialization 36 //-------------------------------------------------------------------------- 37 38 /** 39 * @param prefix string prefix for config properties 40 */ 41 public AverageED(String prefix) { super(prefix); } 42 43 44 //-------------------------------------------------------------------------- 45 // methods 46 //-------------------------------------------------------------------------- 47 48 /** 49 * This is the standard method the define periodic activity. 50 * The frequency of execution of this method is defined by a 51 * {@link peersim.edsim.CDScheduler} component in the configuration. 52 */ 53 public void nextCycle( Node node, int pid ) //这里就是周期模式的核心代码部分,定义了周期性的行为 54 { 55 Linkable linkable = 56 (Linkable) node.getProtocol( FastConfig.getLinkable(pid) ); 57 if (linkable.degree() > 0) 58 { 59 Node peern = linkable.getNeighbor( 60 CommonState.r.nextInt(linkable.degree())); //这部分的功能是得到本地节点的一个邻居节点,而不是所有相邻节点 61 62 // XXX quick and dirty handling of failures 63 // (message would be lost anyway, we save time) 64 if(!peern.isUp()) return; 65 66 ((Transport)node.getProtocol(FastConfig.getTransport(pid))). //这里涉及到了传输层,功能是像邻居节点发送信息,把本地的值发过去 67 send( 68 node, 69 peern, 70 new AverageMessage(value,node), 71 pid); 72 } 73 } 74 75 //-------------------------------------------------------------------------- 76 77 /** 78 * This is the standard method to define to process incoming messages. 79 */ 80 public void processEvent( Node node, int pid, Object event ) { //这里是ED模式的核心代码部分,用来处理事件 81 82 AverageMessage aem = (AverageMessage)event; //从邻居节点那里接受到的信息 83 84 if( aem.sender!=null ) //如果邻居节点的发送者不为空,说明本节点并不是目的节点,所以继续帮他转发 85 ((Transport)node.getProtocol(FastConfig.getTransport(pid))). 86 send( 87 node, 88 aem.sender, 89 new AverageMessage(value,null), 90 pid); 91 92 value = (value + aem.value) / 2; //如果为空,则说明本节点就是目的节点,所以把对方的值和本地的平均值替换本地值 93 } 94 95 } 96 97 //-------------------------------------------------------------------------- 98 //-------------------------------------------------------------------------- 99 100 /** 101 * The type of a message. It contains a value of type double and the 102 * sender node of type {@link peersim.core.Node}. 103 */ 104 class AverageMessage { //信息类,非常简单,只有一个value和sender 105 106 final double value; 107 /** If not null, 108 this has to be answered, otherwise this is the answer. */ 109 final Node sender; 110 public AverageMessage( double value, Node sender ) 111 { 112 this.value = value; 113 this.sender = sender; 114 } 115 }
以上就是ed模式下的一个简单的样例,功能也很简单,对比下周期模式,我觉得他是这么工作的:在每个定义的周期内向邻居发送节点,当节点接受到发送来的信息后,则会处理(求平均值),其中内部部分是通过一个堆来管理这些事件(send()方法本身就是把事件添加到堆当中)
然而难点并不是这,而是配置文件部分。。。shit :(
贴代码
1 # network size #首先是类似宏定义的一样定义了几个值,方便一会使用,果然换了ED模式连这里都高级起来了
2 SIZE 1000
3
4 # parameters of periodic execution
5 CYCLES 100
6 CYCLE SIZE*10000
7
8 # parameters of message transfer
9 # delay values here are relative to cycle length, in percentage,
10 # eg 50 means half the cycle length, 200 twice the cycle length, etc.
11 MINDELAY 0
12 MAXDELAY 0
13 # drop is a probability, 0<=DROP<=1
14 DROP 0
15
16 random.seed 1234567890
17 network.size SIZE
18 simulation.endtime CYCLE*CYCLES
19 simulation.logtime CYCLE
20
21 ################### protocols =========================== #这部分比较麻烦,全是新的玩意
22
23 protocol.link peersim.core.IdleProtocol #网络还是选的之前的一样
24
25 protocol.avg example.edaggregation.AverageED
26 protocol.avg.linkable link
27 protocol.avg.step CYCLE #这里的step类似于周期的概念
28 protocol.avg.transport tr #这里的tr在下面有定义
29
30 protocol.urt UniformRandomTransport #这里是具体的传输层协议,功能是以随机的延迟(随机范围在下面定义)发送消息,发送的实质是向事件的堆中添加事件
31 protocol.urt.mindelay (CYCLE*MINDELAY)/100
32 protocol.urt.maxdelay (CYCLE*MAXDELAY)/100
33
34 protocol.tr UnreliableTransport #一个不稳定的传输层协议,以下面的drop的值随机丢包,实际传输还是用的上面urt
35 protocol.tr.transport urt
36 protocol.tr.drop DROP
37
38 ################### initialization ======================
39
40 init.rndlink WireKOut #网络布局,节点以k出度相连
41 init.rndlink.k 20
42 init.rndlink.protocol link
43
44 init.vals LinearDistribution #给每个节点的赋初值,线性分布,具体分布方法是定义step= (max.doubleValue()-min.doubleValue())/(Network.size()-1); setter.set(i,Math.round(i*step)+min.longValue()); 详细见源文件
45 init.vals.protocol avg
46 init.vals.max SIZE
47 init.vals.min 1
48
49 init.sch CDScheduler #这里很关键,定义了一个周期调度管理器,会在每个周期的开始随机打乱节点的部分,每隔一个cycle值就打乱一次
50 init.sch.protocol avg
51 init.sch.randstart
52
53 ################ control ==============================
54
55 control.0 SingleValueObserver #这里的step指定了周期值,使得监测者也会在每个指定的周期调用一次,否则control则会想周期模式一样调度
56 control.0.protocol avg
57 control.0.step CYCLE
最后贴上实验结果:
EDSimulator: resetting
Network: no node defined, using GeneralNode
EDSimulator: running initializers
- Running initializer init.rndlink: class peersim.dynamics.WireKOut
- Running initializer init.sch: class peersim.edsim.CDScheduler
- Running initializer init.vals: class peersim.vector.LinearDistribution
EDSimulator: loaded controls [control.0]
Current time: 0
control.0: 1.0 1000.0 1000 500.5 83416.66666666667 1 1
Current time: 10000000
control.0: 37.5 919.0 1000 500.5 25724.159091250687 1 1
Current time: 20000000
control.0: 206.7109375 767.890625 1000 500.5 8096.807036889389 1 1
Current time: 30000000
control.0: 352.373046875 695.453125 1000 500.5 2578.022573176135 1 1
Current time: 40000000
control.0: 412.430419921875 625.474609375 1000 500.5 801.1082179446831 1 1
Current time: 50000000
control.0: 436.43787479400635 570.459858417511 1000 500.5 243.53994072762902 1 1
Current time: 60000000
control.0: 470.7608990445733 527.0359845032217 1000 500.49999999999994 74.13788674564383 1 2
Current time: 70000000
control.0: 483.6040476858616 518.0301055684686 1000 500.49999999999903 23.428974301677556 1 1
Current time: 80000000
control.0: 490.5196089811798 512.0301471857779 1000 500.4999999999993 7.285566419597019 1 1
Current time: 90000000
control.0: 494.97216907397836 506.0375954180854 1000 500.4999999999999 2.1798299307442246 1 1
Current time: 100000000
control.0: 497.18190345272336 503.5837144460532 1000 500.5000000000001 0.6073148838336206 1 1
Current time: 110000000
control.0: 498.54320551492475 502.3533156558903 1000 500.5 0.1786794435445898 1 2
Current time: 120000000
control.0: 499.4023441821402 501.4962048486104 1000 500.49999999999966 0.055257607540637785 1 1
Current time: 130000000
control.0: 500.0032071191514 501.09832936709677 1000 500.4999999999995 0.017914865984002482 1 1
Current time: 140000000
control.0: 500.2115701087355 500.83018846682955 1000 500.5000000000003 0.005681541785868155 1 1
Current time: 150000000
control.0: 500.34130672550015 500.6817038675913 1000 500.49999999999983 0.0018027434356275712 1 1
Current time: 160000000
control.0: 500.4099993828274 500.593872603867 1000 500.50000000000006 5.362825330674977E-4 1 1
Current time: 170000000
control.0: 500.45257293353984 500.54348273631905 1000 500.50000000000057 1.540724446790086E-4 1 1
Current time: 180000000
control.0: 500.4730336913324 500.5308245606462 1000 500.49999999999983 4.870521656989873E-5 2 1
Current time: 190000000
control.0: 500.48375224793585 500.5157654498322 1000 500.4999999999995 1.6009524787167412E-5 1 1
Current time: 200000000
control.0: 500.48865909872677 500.50651976294216 1000 500.50000000000017 5.077729859315717E-6 1 1
Current time: 210000000
control.0: 500.4951192430326 500.5047676794802 1000 500.5000000000002 1.6155684864646324E-6 1 1
Current time: 220000000
control.0: 500.4974085478983 500.502935896735 1000 500.50000000000045 5.105843169016166E-7 1 1
Current time: 230000000
control.0: 500.4987222960319 500.5016402188968 1000 500.5000000000002 1.6512563666543207E-7 1 1
Current time: 240000000
control.0: 500.49903235648463 500.50092451432386 1000 500.49999999999994 5.299286046125987E-8 1 1
Current time: 250000000
control.0: 500.49958979342233 500.50059026547086 1000 500.5000000000001 1.5440470612681545E-8 1 1
Current time: 260000000
control.0: 500.4996881991682 500.500274943262 1000 500.5000000000001 4.8652048911656945E-9 1 1
Current time: 270000000
control.0: 500.49977403242923 500.5001382754437 1000 500.4999999999995 2.0101744759906163E-9 1 1
Current time: 280000000
control.0: 500.49987495360983 500.50007640960587 1000 500.5 1.7479778052092316E-10 1 1
Current time: 290000000
control.0: 500.49994445650935 500.5000501190701 1000 500.5000000000004 0.0 1 1
Current time: 300000000
control.0: 500.4999661034419 500.50002345424616 1000 500.49999999999994 3.2046259762169247E-10 1 1
Current time: 310000000
control.0: 500.4999712575856 500.50001450012803 1000 500.5000000000001 0.0 1 1
Current time: 320000000
control.0: 500.49998996075124 500.50001003198986 1000 500.5000000000003 0.0 1 1
Current time: 330000000
control.0: 500.4999953242251 500.5000043994592 1000 500.50000000000045 0.0 1 1
Current time: 340000000
control.0: 500.4999966553132 500.5000031137919 1000 500.49999999999994 5.826592684030772E-11 2 1
Current time: 350000000
control.0: 500.49999822203824 500.50000161478096 1000 500.49999999999994 2.6219667078138473E-10 1 1
Current time: 360000000
control.0: 500.4999990494662 500.5000007140138 1000 500.4999999999997 4.0786148788215407E-10 1 1
Current time: 370000000
control.0: 500.49999953087456 500.5000003780667 1000 500.50000000000057 0.0 1 1
Current time: 380000000
control.0: 500.4999997027671 500.5000002330102 1000 500.50000000000006 0.0 1 1
Current time: 390000000
control.0: 500.49999980445176 500.5000001249846 1000 500.5000000000003 0.0 1 1
Current time: 400000000
control.0: 500.4999998909826 500.5000000637969 1000 500.50000000000017 0.0 2 1
Current time: 410000000
control.0: 500.4999999491945 500.50000003001117 1000 500.50000000000006 2.330637073612309E-10 1 1
Current time: 420000000
control.0: 500.49999997587577 500.500000020472 1000 500.5000000000005 0.0 1 1
Current time: 430000000
control.0: 500.4999999853711 500.5000000123341 1000 500.49999999999966 1.456648171007693E-10 1 1
Current time: 440000000
control.0: 500.4999999932832 500.500000006375 1000 500.5 0.0 1 1
Current time: 450000000
control.0: 500.4999999963538 500.50000000440656 1000 500.5000000000004 0.0 1 1
Current time: 460000000
control.0: 500.4999999981322 500.50000000189016 1000 500.4999999999998 4.952603781426156E-10 1 1
Current time: 470000000
control.0: 500.49999999882857 500.50000000100374 1000 500.5000000000001 2.913296342015386E-11 1 1
Current time: 480000000
control.0: 500.4999999993252 500.5000000005659 1000 500.49999999999983 8.739889026046158E-11 1 1
Current time: 490000000
control.0: 500.49999999949034 500.500000000275 1000 500.50000000000006 5.826592684030772E-11 1 1
Current time: 500000000
control.0: 500.49999999982185 500.500000000164 1000 500.50000000000006 2.6219667078138473E-10 1 1
Current time: 510000000
control.0: 500.4999999998772 500.5000000001006 1000 500.49999999999983 3.7872852446200017E-10 1 1
Current time: 520000000
control.0: 500.4999999999419 500.50000000005065 1000 500.4999999999994 7.574570489240003E-10 1 1
Current time: 530000000
control.0: 500.4999999999752 500.5000000000325 1000 500.5000000000001 0.0 1 2
Current time: 540000000
control.0: 500.49999999998687 500.5000000000167 1000 500.50000000000006 0.0 1 1
Current time: 550000000
control.0: 500.4999999999914 500.50000000000847 1000 500.5 5.826592684030772E-11 1 1
Current time: 560000000
control.0: 500.4999999999958 500.5000000000048 1000 500.5 0.0 1 2
Current time: 570000000
control.0: 500.49999999999693 500.50000000000296 1000 500.5 0.0 1 1
Current time: 580000000
control.0: 500.4999999999983 500.50000000000153 1000 500.5 0.0 1 1
Current time: 590000000
control.0: 500.49999999999886 500.5000000000009 1000 500.5 0.0 1 1
Current time: 600000000
control.0: 500.4999999999992 500.50000000000045 1000 500.5 0.0 1 3
Current time: 610000000
control.0: 500.49999999999966 500.5000000000003 1000 500.5 0.0 1 2
Current time: 620000000
control.0: 500.49999999999983 500.50000000000017 1000 500.5 0.0 4 1
Current time: 630000000
control.0: 500.4999999999999 500.5000000000001 1000 500.5 0.0 9 2
Current time: 640000000
control.0: 500.49999999999994 500.5 1000 500.5 0.0 10 990
Current time: 650000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 660000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 670000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 680000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 690000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 700000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 710000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 720000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 730000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 740000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 750000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 760000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 770000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 780000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 790000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 800000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 810000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 820000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 830000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 840000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 850000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 860000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 870000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 880000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 890000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 900000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 910000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 920000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 930000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 940000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 950000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 960000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 970000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 980000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
Current time: 990000000
control.0: 500.5 500.5 1000 500.5 0.0 1000 1000
EDSimulator: queue is empty, quitting at time 999980413
首先大概介绍BT网络运行的整体流程:
开始阶段,一个节点加入到网络中,并向tracker节点发送信息,tracker返回若干个邻居的列表
得到列表后,向每个邻居发送bitfiled信息,来获取他们的文件状态。接着确定需要的piece,并向拥有该
piece的邻居发送关注的请求消息。本地节点根据过去20s内邻居节点的带宽传输表现,选出前3,并把它们置为疏通状态,向他们发送块的请求。
当收到请求信息时,返回一个piece信息,注意如果本地节点上传少于10个块,就把当前请求入队,按队列顺序一个个请求处理,直到上传了10个块。
每当一个节点完成了一个piece的下载,就会给所有邻居发送一个hava信息,表明自己有可以分享的piece
接下来贴上bittorent.java,附有自己添加的注释
BT网络中涉及到了许多小的算法,例如块的选择,如何确定阻塞疏通状态等,这里附上
下载文件片断的选择(Piece Selection)
选择一个好的顺序来下载片断,对提高性能非常重要。一个差的片断选择算法可能导致所有的片断都处于下载中,或者另一种情况,没有任何片断被上载给其它 peers。
1)严格的优先级(Strict Priority)
片断选择的第一个策略是:一旦请求了某个片断的子片断,那么该片断剩下的子片断优先被请求。这样,可以尽可能快的获得一个完整的片断。
2)最少的优先(Rarest First)
对一个下载者来说,在选择下一个被下载的片断时,通常选择的是它的peers们所拥有的最少的那个片断,也就是所谓的“最少优先”。这种技术,确保了每个下载者都拥有它的peers们最希望得到的那些片断,从而一旦有需要,上载就可以开始。这也确保了那些越普通的片断越放在最后下载,从而减少了这样一种可能性,即某个peer当前正提供上载,而随后却没有任何的被别人感兴趣的片断了。也就说说,每个peer都优先选择整个系统中最少的那些片断去下载,而那些在系统中相对较多的片断,放在后面下载,这样,整个系统就趋向于一种更优的状态。如果不用这种算法,大家都去下载最多的那些片断,那么这些片断就会在系统中分布的越来越多,而那些在系统中相对较少的片断仍然很少,最后,某些 peer 就不再拥有其它 peer 感兴趣的片断了,那么系统的参与者越来越少,整个系统的性能就下降。
在BT系统中,充分考虑了经济学的概念,处处从整个系统的性能出发,参与者越多,系统越优化。
信息理论显示除非种子上传了文件的所有片断,否则没有任何下载者可以完成所有文件的下载。如果在一个部署中,只有一个种子,而且种子的上载能力比它的大多数下载者都要差,那么,不同的下载者从种子那里下载不同的片断,性能就会变得比较好,因为,重复的下载浪费了种子获取更多信息的机会。“最少优先”使得下载者只从种子处下载新的片断(也就是整个系统中其它peer都没有的片断),因为,下载者能够看到其它peers那里已经有了种子已经上传的片断。
在某些部署中,原始的种子由于某些原因最终关闭,只好由剩下的这些下载者们来负责上传。这样显然会带来一个风险:某些片断任何一个下载者都不拥有。“最少优先”也很好的处理了这种情况。通过尽快的复制最少的片断,减少了这种由于当前的peers停止上载后带来的风险。
3)随机的第一个片断(Random First Piece)
“ 最少优先”的一个例外是在下载刚开始的时候。此时,下载者没有任何片断可供上传,所以,需要尽快的获取一个完整的片断。而最少的片断,通常只有某一个peer拥有,所以,它可能比多个peers都拥有的那些片断下载的要慢。因此,第一个片断是随机选择的,直到第一个片断下载完成,才切换到“最少优先”的策略。
4)最后阶段模式(Endgame Mode)
有时候,从一个速率很慢的peer那里请求一个片断。在下载的中间阶段,这不是什么问题,但是却可能潜在的延迟下载的完成。为了防止这种情况,在最后阶段,peer向它的所有的peers们都发送某片断的子片断的请求,一旦某些子片断到了,那么就会向其它peer发送 cancel 消息,取消对这些子片断的请求,以避免带宽的浪费。实际上,用这种方法并没有浪费多少带宽,而文件的结束部分也一直下载的非常快。
2、阻塞算法(Choking Algorithms)
BT 并不集中分配资源。每个peer自己有责任来尽可能的提高它的下载速率。Peers从它可以连接的peers处下载文件,并根据对方提供的下载速率给予同等的上传回报(你敬我一尺,我敬你一丈)。对于合作者,提供上传服务,对于不合作的,就阻塞对方。所以说,阻塞是一种临时的拒绝上传策略,虽然上传停止了,但是下载仍然继续。在阻塞停止的时候,连接并不需要重新建立。
阻塞算法并不属于BT对等协议(指peers 之间交互的协议)的技术部分,但是对提高性能是必要的。一个好的阻塞算法应该利用所有可用的资源,为所有下载者提供一致可靠的下载速率,并适当惩罚那些只下载而不上传的peers。
1)帕累托效率(Pareto Efficiency)
在经济学里,帕累托效率可以这样来定义:一种状态(资源配置、社会制度等)被称为帕累托最优状态,如果不存在另外一种可选择的状态使得没有任何人的处境变差而至少有一个人的处境变得更好。这意味着,当满足给定的约束条件,一种资源配置的状态已经使没有人能够按照自己的偏好在不损害别人的条件下变得更好,那么就是达到了帕累托最优状态。可以通俗地理解为,如果处于这种状态:除非损人,就不能利己,这就达到了帕累托最优。在计算机领域,寻求帕累托有效是一种本地优化算法BitTorrent的阻塞算法,用一种针锋相对的方式来试图达到帕累托最优。(原文不太好翻译,我简化了)。Peers对那些向他提供上传服务的peers给予同样的回报,目的是希望在任何时候都有若干个连接正在进行着双向传输。
2)BitTorrent的阻塞算法
从技术层面上说,BT的每个peer一直与固定数量的其它 peers 保持疏通(通常是4个),所以问题就变成了哪些peers应该保持疏通?这种方法使得TCP的拥塞控制性能能够可靠的饱和上传容量。(也就是说,尽量让整个系统的上传能力达到最大)。
严格的根据当前的下载速率来决定哪些peers应该保持疏通。令人惊讶的是,计算当前下载速率是个大难题。当前的实现实质上是一个每隔20秒的轮询。而原来的算法是对一个长时间的网络传输进行总计,但这种方法很差劲,因为由于资源可用或者不可用,带宽会变化的很快。
为了避免因为频繁的阻塞和疏通 peers造成的资源浪费,BT每隔10秒计算一次哪个peer需要被阻塞,然后将这种状态保持到下一个10秒。10秒已经足够使得TCP来调整它的传输性能到最大。
3)开放检测(Optimistic Unchoking)
如果只是简单的为提供最好的下载速率的peers们提供上载,那么就没有办法来发现那些空闲的连接是否比当前正使用的连接更好。为了解决这个问题,在任何时候,每个peer都拥有一个称为“optimistic unchoking”的连接,这个连接总是保持疏通状态,而不管它的下载速率是怎样。每隔30秒,重新计算一次哪个连接应该是“optimistic unchoking”。30秒足以让上传能力达到最大,下载能力也相应的达到最大。这种和针锋相对类似的思想非常的伟大。“optimistic unchoking”非常和谐的与“囚徒困境”合作。
4)反对歧视(Anti-snubbing)
某些情况下,一个peer可能被它所有的peers都阻塞了,这种情况下,它将会保持较低的下载速率直到通过 “optimistic unchoking”找到更好peers。为了减轻这种问题,如果一段时间过后,从某个peer那里一个片断也没有得到,那么这个peer认为自己被对方 “怠慢”了,于是不再为对方提供上传,除非对方是“optimistic unchoking”。这种情况频繁发生,会导致多于一个的并发的“optimistic unchoking”。
5)仅仅上传(Upload Only)
一旦某个peer完成了下载,它不能再通过下载速率(因为下载速率已经为0了)来决定为哪些 peers 提供上载了。目前采用的解决办法是,优先选择那些从它这里得到更好的上载速率的peers。这样的理由是可以尽可能的利用上载带宽。