用于ccp的portus实现的python绑定

portus的Python项目详细描述


皮波特斯

该模块为portus ccp实现提供了一个python接口。

设置

要构建和使用python绑定,还需要setuptools\u rust

sudo pip install setuptools_rust

你需要告诉它使用Rust的夜间版本,因为有些功能 仍在实验中:

  • 检查包的安装位置:pip show setuptools_rust
  • 编辑packages/setuptools_rust/build.py
  • 搜索包含“rustc”的行(应该是~102),并将参数更改为["cargo", "+nightly", "rustc", ...

现在,您可以使用

python setup.py develop

根据您的python环境设置,您可能需要使用sudo运行此命令。 (并确保您的PATH变量被保留):

sudo env PATH=$PATH python setup.py develop

现在您应该可以像这样导入包:

importportus

编写算法

概述

portus中的算法由python类表示,此类的实例表示单个tcp流。为每个流创建一个新实例

这个类必须是portus.AlgBase的子类,并且必须实现两个 以下方法签名:

  • on_create(self)
  • on_report(self, r)
    • r是一个报表对象,包含数据路径程序中定义的所有字段,以及当前的CwndRate。假设您的程序只定义了一个变量:(def (acked 0)),其中acked将自上次报告以来确认的总字节相加。此值可以作为r.acked访问。类似地,您可以访问cwnd或按r.Cwndr.Rate(重要的字幕化!).

类的每个实例化将自动在self中有两个字段:

  • self.datapath是指向可用于安装的datapath对象的指针 新的数据路径程序。它有两种可用的方法:
    1. datapath.install( str ),它将数据路径程序作为字符串。它编译程序并将其安装在数据路径中。它不返回任何内容,但如果程序无法编译,它可能会引发异常。
    2. datapath.update_field(field, val),它接受数据路径程序的Report范围内的变量,并将值设置为val。例如,要仅更新cwnd,可以使用datapath.update_field("Cwnd", 10000)(注意:cwnd以字节表示,而不是以数据包表示)。
  • self.datapath_info是一个包含来自数据路径的这个特定流的字段的结构(例如,可以在on_create中使用它来基于数据路径的mss设置初始cwnd)
    • sock_id:数据路径中此流的唯一ID
    • init_cwnd:此流在设置之前将具有的初始拥塞窗口
    • src_ipsrc_portdst_ipdst_port:流的源和目标的IP地址和端口

数据路径程序

数据路径程序用于(1)定义哪些统计信息要发送回您的usespace程序,以及多长时间和(2)设置拥塞窗口和/或速率。数据路径程序是用一种非常简单的类似lisp的方言编写的,它由一个单独的变量定义行和任意数量的when子句组成:

(def ( ... ) ( ... ))
(when (event) (
  do_stuff ...
)
(when (other_event) (
    do_other_stuff ...
)

注意:以下信息已过期,因为datapath程序api已

已更新

1.报表变量定义

示例:(def (Report.acked 0) (Report.rtt 0) (Report.timeout false))

此行定义report作用域中变量的名称和初始值。在datapath程序中调用(report)会导致使用这些变量的当前值调用算法的on_report函数。调用后,这些变量将重置回其初始值。

注意:数据路径程序中的变量被写成{scope}.{name}。例如,Report作用域中的acked变量被写为Report.acked。因此,此行定义的所有变量必须以Report.开头,但是,当您在on_report中访问它们时,只需提供变量名。在上面的例子中,Report.rtt定义了Report范围中的变量rtt。如果我们想在on_report(r)中访问这个值,我们将使用r.rtt(即notr.Report.rtt)。

2。当子句

when子句由布尔表达式和一组指令组成。在每个ack上,数据路径检查布尔表达式,如果其计算结果为true,则运行一组指令。例如,下面的when子句每rtt发送一次报告(即调用on_report函数):

(when (> Micros Flow.rtt_sample_us)
    (report)
)

总而言之

显示完整API的示例算法定义:

importportus# Class must sublcass portus.AlgBaseclassSampleCCAlg(portus.AlgBase):# Init must take exactly these parametersdef__init__(self,datapath,datapath_info):# Store a copy of the datapath and info for laterself.datapath=datapathself.datapath_info=datapath_info# Internally store an initial cwnd valueself.cwnd=10*self.datapath_info.mss# Install an initial datapath program to keep track of the RTT and report it once per RTT# The first when clause is true on every single ack,#    which means the 'Report.rtt' field will always keep the latest rtt sample# The second when clause is true once one rtt's worth of time has passed, #    at which point it will trigger on_report, and Micros (and Report.rtt) will be reset to 0self.datapath.install("""\    (def        (Report.rtt 0)    )    (when true        (:= Report.rtt Flow.rtt_sample_us)        (fallthrough)    )    (when (> Micros Flow.rtt_sample_us)        (report)    )    """)# This function will be called once per RTT, and the report struct `r` will contain:# "rtt", "Cwnd", and "Rate"defon_report(self,r):# Compute new cwnd internally # If the rtt has decreased, increase the cwnd by 1 packet, else decrease by 1 packetifself.last_rtt<r.rtt:self.cwnd+=self.datapath_info.msselse:self.cwnd-=self.datapath_info.mssself.last_rtt=r.rtt# Send this new value of cwnd to the datapathself.datapath.update_field("Cwnd",self.cwnd)

重要注意事项

  1. 您应该在__init__实现中安装一个初始数据路径程序,否则您将不会收到任何报告,也不会发生任何其他情况。以后处理on_report时,始终可以安装其他数据路径程序。
  2. 如果要打印任何内容,应该使用sys.stderr.write()(注意,您需要import sys,并且它不会像print那样自动为您添加新行)。
  3. 必须将对datapath的引用存储在名为“datapath”(即self.datapath = datapath)的self中,因为库在内部也使用它来访问datapath结构。

启动ccp

ccp入口点是portus.connect(ipc_type, class, debug, blocking)

  • ipc_type (string):(netlink unix char)在linux上或(unix)在mac上
  • class:您的算法类,例如SampleCCAlg
  • debug (bool):如果为true,则ccp将记录ccp和datapath之间传递的所有消息
  • blocking (bool):如果为true,则使用阻塞ipc读取,否则使用非阻塞

例如:portus.connect("netlink", SampleCCAlg, debug=True, blocking=True)

不管您使用的是阻塞还是非阻塞套接字,connect都将永远阻塞(要停止ccp,只需发送ctrl+c或终止进程)。

示例

有关定义算法和运行ccp的完整工作示例,请参见./aimd.py中的简单aimd方案,并尝试运行它:sudo python aimd.py

欢迎加入QQ群-->: 979659372 Python中文网_新手群

推荐PyPI第三方库


热门话题
文本中的java JFX图像   堆栈快速java问题   Web服务上的java设置超时   找不到java Jersey MessageBodyReader   尝试运行TestNG类时,Eclipse中线程“main”中出现java异常错误   java Wakelock只工作一次   多线程Java同步和线程   java日期解析操作使服务器崩溃   在Bluemix中启动应用程序时,java无法创建PoolableConnectionFactory错误   java包装是否超出了可用空间中组合框的内容?   java安卓游戏时间处理   根据Java,spring是线程安全的方法   正则表达式如何使用java查找中间有空格的数字的正则表达式模式   java使用数组作为自定义通用哈希表中的表来存储条目   java中缀到后缀求值   java类型安全:Map[]类型的表达式需要未经检查的转换才能符合Map<String,Object>[]   java Jama矩阵printwriter错误   java在使用GridLayout创建战舰程序时遇到问题