Archive

Archive for the ‘计算机网络’ Category

PeerSim 源代码分析之一:程序入口

March 17th, 2011 leeing No comments

PeerSim 的文档资料很少,有很多地方看上去概念很模糊,去年曾经翻译过官方的几篇文档,按顺序汇总如下:

当时翻译的时候,并没有深入地去学习,最近由于仿真的需要,又静下心来研究了几天,有些东西发现在文档中是无法得到一个很清晰的解释,看了一下PeerSim的源代码规模也并不是很大,所以决定 RTFSC (Read the F *** ing Source Code : –) ,源代码本身就是最好的学习资料,当然,这需要足够的耐心。

不过不得不说的是 PeerSim 的源代码的缩进真是有点混乱。

首先,是程序的入口 peersim.Simulator.java:

package peersim;

import java.io.*;

import peersim.cdsim.*;
import peersim.config.*;
import peersim.core.*;
import peersim.edsim.*;

/**
 * peersim.Simulator.java
 *
 * 程序的入口,主要作用就是读取配置文件,并根据仿真类型来调用仿真引擎。
 */
public class Simulator {

    // 某些静态变量,一看就懂。

    public static final int CDSIM = 0;

    public static final int EDSIM = 1;

    public static final int UNKNOWN = -1;

    protected static final String[] simName = {
        "peersim.cdsim.CDSimulator",
        "peersim.edsim.EDSimulator",};

    // 配置文件中的 simulation.experiments 参数,如果没有标明,则默认为
    // 进行1次实验
    public static final String PAR_EXPS = "simulation.experiments";

    // 设置程序的输出,默认为 stdout
    public static final String PAR_REDIRECT = "simulation.stdout";

    // 仿真类型,有3种,即 CDSIM,EDSIM 和 UNKNOWN
    private static int simID = UNKNOWN;

    // 根据配置文件返回当前的仿真类型
    public static int getSimID() {

        if (simID == UNKNOWN) {
            // 怎么判断类型?很简单,看配置文件里有没有
	    // 定义 simulation.cycles 的参数
            if (CDSimulator.isConfigurationCycleDriven()) {
                simID = CDSIM;
            } else if (EDSimulator.isConfigurationEventDriven()) {
                // 类似的,如果配置文件里有 simulation.endtime 的定义,
                // 就是 Event-driven 模式
                simID = EDSIM;
            }
        }
        return simID;
    }

    // 程序的入口,运行时要将配置文件的位置作为参数提供给 Simulator
    public static void main(String[] args) {
        long time = System.currentTimeMillis();

        System.err.println("Simulator: loading configuration");

        // 读入配置文件
        Configuration.setConfig(new ParsedProperties(args));

        // 设置输出到某一个 PrintStream,默认为 System.out
        PrintStream newout =(PrintStream)
		Configuration.getInstance(PAR_REDIRECT, System.out);

        if (newout != System.out) {
            System.setOut(newout);
        }

        // 设置实验的次数,默认为1次,可以通过设置 simulation.experiments
		// 来改变默认值。
        // 在这里说一下,PeerSim 的配置文件学习是第一步,想要编写仿真
        // 首先就要明白 PeerSim 是如何解析配置文件的,具体的解析可以看
        // peersim.config 包里边的类。
        int exps = Configuration.getInt(PAR_EXPS, 1);

        // 读取实验的类型,如果不能确定仿真类型,就退出。
        final int SIMID = getSimID();
        if (SIMID == UNKNOWN) {
            System.err.println(
    	"Simulator: unable to determine simulation engine type");
            return;
        }

        try {

            for (int k = 0; k < exps; ++k) { // 一次循环进行一次实验
                if (k > 0) {
                    // 仿真过程中的种子,可以通过在配置文件中的
		    	// random.seed 来设置。
                    // 如果不设置的话,就将当前的时间作为种子
                    long seed = CommonState.r.nextLong();
                    CommonState.initializeRandom(seed);
                }
                System.err.print(
			"Simulator: starting experiment " + k);
                System.err.println(" invoking " + simName[SIMID]);
                System.err.println("Random seed: "
			+ CommonState.r.getLastSeed());
                System.out.println("\n\n");

                // 作者说可以用反射机制的,不过这样写容易理解。
  			// 我个人觉得没必要用反射。
                // 根据仿真的类型,调用相应的仿真引擎。
                switch (SIMID) {
                    case CDSIM:
                        CDSimulator.nextExperiment();
				// 具体怎么运行且听下文分解
                        break;
                    case EDSIM:
                        EDSimulator.nextExperiment();
				// 同上
                        break;
                }
            }

        } catch (MissingParameterException e) {
            System.err.println(e + "");
            System.exit(1);
        } catch (IllegalParameterException e) {
            System.err.println(e + "");
            System.exit(1);
        }

        // undocumented testing capabilities
        // 这一部份源码没有任何说明,看样子作者是用来做测试的
        if (Configuration.contains("__t")) {
            System.out.println(System.currentTimeMillis() - time);
        }
        if (Configuration.contains("__x")) {
            Network.test();
        }

    }
}

好吧,程序的入口就分析到这里。下次就分析 Cycle-based 仿真核心 CDSimulator 的代码。

Categories: PeerSim Tags:

IPV6 Tracker : 从 PPA 安装 Transmission 2.21

February 22nd, 2011 leeing No comments

这两天一直在安装配置 Transmission,由于Ubuntu 源中的 Transmission 版本是2.0.5,经过试用之后,发现默认对 IPV6 的支持不好,无法连接北邮人BT的Tracker,于是开始了漫漫的修改源码+编译的旅程(关于编译,又是很多稀奇古怪的问题出现),虽然最终成功编译出二进制文件,但很奇怪的是自行编译的 Transmission 一旦打开一个种子,很快就CPU占用率飙升,最终进程 transmission-daemon 僵死 – -!

Transmission 2.21的Changelog:

  • Fix compile error in the the 2.20 tarball
  • File re-verification is no longer needed in some situations
  • Fix “Too many open files” error
  • Show the total downloading and seeding time per torrent
  • Fix webseeds
  • Better support for IPv6-only trackers
  • Add the ability to shutdown Transmission sessions via RPC
  • NAT-PMP and UPnP now also map the UDP port
  • Update the DHT code to dht-0.18
  • Faster parsing of bencoded data
  • Improve support for running scripts when a torrent finishes downloading
  • Fix reannounce interval when trackers return a 404 error
  • Fix checksum error on platforms running uClibc 0.9.27 or older
  • Fix memmem() errors on Solaris

Read more…

Categories: BT, Ubuntu Tags: , , ,

JXTA/JXSE 2.6 的最新消息

September 29th, 2010 leeing No comments

JXTA/JXSE 2.6

JXTA 是什么?请参见 百度百科

刚刚在网上搜索了一下 JXTA 的状态,才知道在几个月前已经出了2.6版本。JXTA在2001年初刚刚被创建时曾被寄予厚望,但是bug不少,文档也很匮乏,在2007年出了2.5版本之后几年没什么动静,断断续续地有少数的snapshot版本发布。

https://jxta-jxse.dev.java.net/ 依旧是2.5版本,其实JXTA已经迁移到 Kenai 平台上,地址是 http://jxse.kenai.com,需要到可以到前面这个网址下载。

关于 JXTA 2.6 的消息在网络上中文信息也很少,blogspot 上倒是有一篇文章《JATX/JXSE 2.6 is out》,大致是说重新启动了这个项目并裁剪重构了很多老的代码,下面简要地说说这个版本的新特性:

  • OSGI支持
  • 任务管理器
  • 缓存管理器
  • 配置对象
  • 连接方法
  • 新的基于Netty的TCP实现
  • 改进的文档

另外,出版了一本新书《Practical JXTA II》。

目前尚不知道JXTA在最近的项目中能否起到什么作用,先暂时看一下。

Read more…

Categories: P2P Tags:

PeerSim 中文教程:Event-driven 模型

July 4th, 2010 leeing No comments

1. 介绍

本教程使用Event-driven模型来演示一个简单的例子,仍然使用的是gossip-based平均数协议,对消息的发送将进行更细节的建模;通过与cycle-based模型的对比,可以发现本协议存在的问题。

在Event-based模型中,除了时间管理和control传递给protocols的方式以外,其它与cycle-based模型相同。不可执行的Protocols(只用于存储数据,比如只存储邻居节点的linkable协议,或存储数值的vectors)可以以同样的方式应用和初始化,在peersim.cdsim包之外的controls也都可以使用。在默认情况下,在cycle-based模型中,controls会的每个周期中调用 ,但在event-based模型中,它们需要进行明确的调度,因为事件驱动模型并不存在周期的概念。

显然,我们可以编写专用于event-based模型的controls,即可以给协议发送事件(消息)。在很多情况下,这是必要的,因为系统经常完全或部分地由外部事件如用户的查询来驱动 ,这能很好地用由生成这些事件,并且驱动仿真执行的controls进行建模。

有些组件是不可用的。例如依赖于静态类peersim.cdsim.CDState(它提供了读取cycle相关的全局状态的接口)的所有组件。我们的经验是,很多依赖于这个状态的 cycle-based 组件可以经过简单的修改并删除这个依赖。

然而,可能有些令人吃惊的是,实现了cycle-based接口的peersim.cdsim.CDProtocol也可以使用于event-based模型,但是必须指出,在大部份的情况下这样做没有什么意义。然而,这个特性的有用之处在于:它让周期性地调用protocols变得很简单,这是一个几乎对所有与housekeeping,失效检测和sending heartbeat message有关的P2P协议来说典型的特性。

2. Protocol

下面以event-based模型来实现平均数协议:

package example.edaggregation;

import peersim.vector.SingleValueHolder;
import peersim.config.*;
import peersim.core.*;
import peersim.transport.Transport;
import peersim.cdsim.CDProtocol;
import peersim.edsim.EDProtocol;

/**
* Event driven version of epidemic averaging.
*/
public class AverageED extends SingleValueHolder
			implements CDProtocol, EDProtocol {

首先,这里同时实现了EDProtocol和CDProtocol接口,前者能让这个类能处理输入的消息,后者则可能令人困惑,因为它属于cycle-based模型的接口。但注意 event-based 的协议不是必须实现CDProtocol接口的,然而想要实现一个可以周期性取得control的协议时,可以通过实现CDProtocol接口,并在配置文件中设置一个CDScheduler 来实现。这样,代码就显得更清晰:以一个单独的组件来管理周期性的执行,而且能单独地进行配置。最后,我们还能简单地将 cycle-based 的协议移植到 event-based 模型上。

Read more…

Categories: P2P, PeerSim Tags:

PeerSim 中文教程:拓扑生成器

July 2nd, 2010 leeing No comments

本教程描述了如何构建一个新的 PeerSim 拓扑生成器。

1. 什么是拓扑?为什么它很重要?

在一个大型的动态P2P系统中,节点没有关于整个网络的信息,而所有的节点都可能拥有一些邻居节点,即节点能”感知”的peers,这种”感知”的关系就定义了一个覆盖网络,这是P2P系统中的一个基本概念。

很多P2P协议都需要在多个不同的网络拓扑上进行实验。PeerSim中的peersim.dynamic.Wire*类已经包含了很多拓扑结构,可以直接用来对linkable协议进行初始化,本教程将展示如何构建一个自定义的拓扑生成器。

2. 一个用来模拟Internet的简单模型

下面我们将编写一个拓扑生成器来构建类似于Internet的树状拓扑,整个构建过程基于一个特定的,与位置相关的preferential attachment方法,编写规则很简单,并且会考虑几何和网络的限制以更好地模拟真实的网络。Preferential attachment由参数a来调整,这个参数能扩大或减少几何位置所带来的影响。

这个规则的策略如下:给定一个单位正方形,将x0置于中心,即x0 = (0.5,0.5),这个节点被称为root,令W()为与root相隔的跳数(hops),对于i=1 … n-1,随机在单位正方形中选择一个xi,然后选择使下面的表达式值最小的节点xj来连接它:

在这里dist()是欧几里德距离而a (alpha)是权重参数,显然,

通过这个方案我们得到了一个x0以为根的树。这个拓扑中每个节点(除了root外)的出度都为1,如果想更深入地理解这个模型,可以参考下面的文章:

  • Heuristically Optimized Trade-offs: A New Paradigm for Power Laws in the Internet
  • Degree distributions of the FKP network model
  • On Power-Law Relationships of the Internet Topology

3. 如何编码

我们的目标是编写一个可以根据 a (alpha)参数生成所需拓扑的PeerSim组件,并且能对生成的拓扑进行分析。这个拓扑可以在仿真过程中逐步生成,也可以用一个步骤生成拓扑,在这里我们倾向后者。为了构建需要的拓扑结构,我们需要下面的组件(注意这只是其中一种方案)。

  • 一个protocol 类,可以存储坐标,它不具备行为元素,只是一个普通的容器。
  • 一个initializer 类,可以为每个节点设置坐标值。
  • 一个control 类, 可在一个任意的linkable协议中根据坐标连接拓扑(在节点间添加link)
  • 一个observer 类,将拓扑结构打印到一个文件中(例如用GnuPlot对图进行可视化)。
  • 一个observer 类,用来收集节点入度的分布的统计数据
  • 一个observer 类,用来测试对随机节点失效的健壮性

在下节我们将看到,一些我们列出来的类是PeerSim中的基本组件,它们都实现了Linkable接口,Linkable以模块化的方式为用户提供了一个能处理任何拓扑结构的抽象。

Read more…

Categories: P2P, PeerSim Tags: