一、前言

前面的博文写到了基于跳数的最短路径的案例实现(ryu实例---基于跳数的最短路径转发_北风-CSDN博客),然而基于跳数的最短路径转发并未考虑网络链路的质量(时延、可用带宽、丢包率...),所以针对这种情况,应该有一种基于链路质量的数据转发方式,所以接下来主要介绍实现链路质量转发的前提知识基础--即使用ryu实现链路网络时延的的探测。

二、时延探测原理

网络时延探测,主要利用LLDP的知识原理进行,关于ryu中的LLDP的原理,可以参考(Ryu拓扑发现原理分析 | SDNLAB | 专注网络创新技术),也就是利用了ryu自带的switches模块的数据,获取到了LLDP数据发送时的时间戳,然后和收到的时间戳进行相减,得到了LLDP数据包从控制器下发到交换机A,然后从交换机A到交换机B,再上报给控制器的时延T1,同理可得到反向的时延T2。此外,控制器到交换机的往返时延,此部分时延可由echo报文测试,分别为Ta,Tb。最后链路的前向后向平均时延T=(T1+T2-Ta-Tb)/2。

所以网络时延探测:(1) echo报文;   (2) LLDP报文;   (3) 运算,这里先主要讲述如何利用echo得到控制器到交换机的时延和LLDP时延,运算部分以及基于链路质量的数据转发后续更新。

三、程序设计

(1) 首先,进行网络拓扑的构建,为了更好提现程序的作用和各个链路时延探测的不同,网络拓扑构建(mininet)如下所示:

(2) 获取控制器到每个交换机的往返时延

这种时延的探测方法主要是控制器通过向交换机发送echo报文,同时记录此时的时间戳,然后交换机收到echo报文之后,就会给控制器返回echo响应报文,当控制器收到响应报文之后,用当前的系统时间减去时间戳,即得到了控制器到交换机的往返时延。具体的代码如下:

    # 由控制器向交换机发送echo报文,同时记录此时时间def send_echo_request(self):# 循环遍历交换机,逐一向存在的交换机发送echo探测报文for datapath in self.dpidSwitch.values():parser = datapath.ofproto_parserecho_req = parser.OFPEchoRequest(datapath, data=bytes("%.12f" % time.time(), encoding="utf8"))  # 获取当前时间datapath.send_msg(echo_req)# 每隔0.5秒向下一个交换机发送echo报文,防止回送报文同时到达控制器hub.sleep(0.5)# 交换机向控制器的echo请求回应报文,收到此报文时,控制器通过当前时间-时间戳,计算出往返时延@set_ev_cls(ofp_event.EventOFPEchoReply, [MAIN_DISPATCHER, CONFIG_DISPATCHER, HANDSHAKE_DISPATCHER])def echo_reply_handler(self, ev):now_timestamp = time.time()try:echo_delay = now_timestamp - eval(ev.msg.data)# 将交换机对应的echo时延写入字典保存起来self.echoDelay[ev.msg.datapath.id] = echo_delayprint('*******************echo delay*****************')print(self.echoDelay)except Exception as error:print(error)return

(3) 获取LLDP时延

获取几个交换机LLDP的逻辑一样,均需要使用到switches模块的数据。计算LLDP时延的处理逻辑如下代码所示。首先从Packet\_in中解析LLDP数据包,获得源DPID,源端口。然后根据发送端口的数据获取到portdata中的发送时间戳数据,并用当下的系统时间减去发送时间戳,得到时延,最后将其保存到字典中。

    @set_ev_cls(ofp_event.EventOFPPacketIn, MAIN_DISPATCHER)def packet_in_handler(self, ev):  # 处理到达的LLDP报文,从而获得LLDP时延msg = ev.msgtry:src_dpid, src_outport = LLDPPacket.lldp_parse(msg.data)  # 获取两个相邻交换机的源交换机dpid和port_no(与目的交换机相连的端口)dst_dpid = msg.datapath.id  # 获取目的交换机(第二个),因为来到控制器的消息是由第二个(目的)交换机上传过来的if self.switches is None:self.switches = lookup_service_brick("switches")  # 获取交换机模块实例# 获得key(Port类实例)和data(PortData类实例)for port in self.switches.ports.keys():  # 开始获取对应交换机端口的发送时间戳if src_dpid == port.dpid and src_outport == port.port_no:  # 匹配keyport_data = self.switches.ports[port]  # 获取满足key条件的values值PortData实例,内部保存了发送LLDP报文时的timestamp信息timestamp = port_data.timestampif timestamp:delay = time.time() - timestampself._save_delay_data(src=src_dpid, dst=dst_dpid, src_port=src_outport, lldp_dealy=delay)except Exception as error:print(error)returndef _save_delay_data(self, src, dst, src_port, lldp_dealy):key = "%s-%s-%s" % (src, src_port, dst)self.src_dstDelay[key] = lldp_dealyprint('------------------lldp delay--------------------')print(self.src_dstDelay)

(4) 整体代码解析

首先,创建类DelayDetector,进行初始化和数据结构的定义,程序用到的包和类代码如下:

import timefrom ryu.base import app_manager
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER, DEAD_DISPATCHER, CONFIG_DISPATCHER, HANDSHAKE_DISPATCHER
from ryu.controller.handler import set_ev_cls
from ryu.lib import hub
from ryu.ofproto import ofproto_v1_3
from ryu.topology.switches import LLDPPacket
from ryu.base.app_manager import lookup_service_brick# 导入这些主要是为了让网络链路中产生LLDP数据包,只有产生了LLDP数据报,才能进行LLDP时延探测
from ryu.topology.api import get_switch, get_link, get_hostclass DelayDetector(app_manager.RyuApp):OFP_VERSIONS = [ofproto_v1_3.OFP_VERSION]def __init__(self, *args, **kwargs):super(DelayDetector, self).__init__(*args, *kwargs)self.name = 'delay_detector'self.switches = lookup_service_brick('switches')# 存储网络拓扑的交换机idself.dpidSwitch = {}# 存储echo往返时延self.echoDelay = {}# 存储LLDP时延self.src_dstDelay = {}# 实现协程,进行时延的周期探测self.detector_thread = hub.spawn(self.detector)# 每隔3秒进行控制器向交换机发送一次echo报文,用以获取往返时延def detector(self):while True:self.send_echo_request()hub.sleep(3)

接下来,就是常规的添加默认流表项的程序代码和记录网络拓扑存在的交换机的程序代码,具体的实现方法不再详述,代码如下:

    def add_flow(self, datapath, priority, match, actions):ofp = datapath.ofprotoofp_parser = datapath.ofproto_parsercommand = ofp.OFPFC_ADDinst = [ofp_parser.OFPInstructionActions(ofp.OFPIT_APPLY_ACTIONS, actions)]req = ofp_parser.OFPFlowMod(datapath=datapath, command=command,priority=priority, match=match, instructions=inst)datapath.send_msg(req)@set_ev_cls(ofp_event.EventOFPSwitchFeatures, CONFIG_DISPATCHER)def switch_features_handler(self, ev):msg = ev.msgdatapath = msg.datapathofp = datapath.ofprotoofp_parser = datapath.ofproto_parser# add table-missmatch = ofp_parser.OFPMatch()actions = [ofp_parser.OFPActionOutput(ofp.OFPP_CONTROLLER, ofp.OFPCML_NO_BUFFER)]self.add_flow(datapath=datapath, priority=0, match=match, actions=actions)@set_ev_cls(ofp_event.EventOFPStateChange, [MAIN_DISPATCHER, DEAD_DISPATCHER])def state_change_handler(self, ev):datapath = ev.datapathif ev.state == MAIN_DISPATCHER:if not datapath.id in self.dpidSwitch:self.dpidSwitch[datapath.id] = datapathelif ev.state == DEAD_DISPATCHER:if datapath.id in self.dpidSwitch:del self.dpidSwitch[datapath.id]

四、实验验证

代码编写完成后,需要对功能进行验证,网络拓扑的构建如上步的拓扑附图所示,运行拓扑。

在Ubuntu命令行输入命令运行ryu代码程序,查看打印的日志文件,如下图所示。

ryu-manager delay_detector_yjl2.py --verbose --observe-links

以上结果中{1: 0.0007786750793457031, 3: 0.0015261173248291016, 2: 0.0006613731384277344}就显示出了控制器到交换机s1、s2、s3往返时延;{'1-2-2': 0.0011858940124511719, '3-2-2': 0.0015857219696044922, '2-3-3': 0.0017540454864501953, '2-2-1': 0.0014941692352294922}显示出了c0-s1-s2-c0、c0-s2-s1-c0、c0-s2-s3-c0、c0-s3-s2-c0这四种LLDP时延。

以上就是网络时延探测的原理和编码,后续会持续更新基于链路质量的数据转发实例(https://blog.csdn.net/weixin_40042248/article/details/117733375)。

GitHub地址:https://github.com/Yang-Jianlin/ryu/blob/master/ryu/app/delay_detector_yjl.py

若有不当之处,请指正,谢谢。

ryu实例---网络时延探测相关推荐

  1. SDN实验(八)——网络时延探测

    SDN实验(八)--网络时延探测 一.原理 二.程序设计 1.构建网络拓扑 2.获取控制器到每个交换机的往返时延 3.获取LLDP时延 4.整体代码 三.实验验证 1.运行Ryu控制器 2.运行网络拓 ...

  2. 了解***的初级阶段---网络信息探测技巧

    了解***的初级阶段---网络信息探测技巧 <?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:offi ...

  3. TTL、Ping包最大字节数、网络时延、抖动、丢包率,看完瞬间变大神!

    Ping是工作在 TCP/IP网络体系结构中应用层的一个服务命令,用于测试网络连接量,以及DNS解析是否正常.通过向特定的目的主机发送 ICMP  Echo 请求报文,测试目的站是否可达及了解其有关状 ...

  4. 计算机网络——网络时延

    目录 1.计算机网络 2.网络时延 3.网络延迟标准和程度的定义 参考文献 1.计算机网络 计算机网络(谢希仁第七版)视频 https://www.bilibili.com/video/BV1yE41 ...

  5. Ubuntu下tc命令配置网络时延、丢包、带宽

    配置网络时延.丢包.带宽等 1. 查看网络流量管理 tc qdisc show 2. 时延 #sudo tc qdisc add dev 网卡名称 root netem delay 时延数值 sudo ...

  6. 思科nat配置实例_思科3750交换机配置DHCP服务器实例网络环境

    思科3750交换机配置DHCP服务器实例网络环境: 一台3750交换机,划分三个vlan, vlan2 为服务器所在网络,命名为server.IP地址段为192.168.2.0,子网掩码:255.25 ...

  7. ftp服务器响应很慢,有果必有因:FTP传输速率慢和TCP窗口、网络时延的因果案例...

    本文要点: 对于TCP协议来说,通信双方一次只能传输TCP窗口大小的数据,然后等待接收方确认,等到确认完毕后才能传输下一段窗口大小的数据. 因此TCP协议的传输速率,取决于TCP传输窗口的大小和网络转 ...

  8. 从云网络时延看应用部署架构

    在引出云网络时延这看起来比较专业的话题前,先看几个比较有意思的问题. 人的最快反应速度是多少毫秒? 机器人最快反应速度是多少毫秒? 这样能在介绍云网络时延时让大家有一个时间量级上的感知. 什么是时延 ...

  9. 应用部署架构:如何降低云网络时延?

    凌云时刻 · 技术 导读:本文通过介绍云网络时延的构成,并对其进行量化分析,分享在不同云网络时延要求下,不同应用对应的部署架构,并简单分析了5G时代对应用部署架构的影响和度量云网络时延的工具. 作者| ...

最新文章

  1. tensorflow gan网络流程图
  2. c#获取电脑硬件信息参数说明(主板篇 Win32_BaseBoard )
  3. Saiku的下载与安装(一)
  4. avr计数_使用8位LCD创建计数器| AVR
  5. html搜题软件,大学搜题app哪个好_大学好的搜题软件_大学搜题免费
  6. [.NET] 《Effective C#》快速笔记(四)- 使用框架
  7. goaccess分析nginx日志
  8. 模拟量输入输出配置及数值的规范化
  9. 第2章 藏书阁签到,修为突破
  10. 解决IIS无响应假死状态
  11. 浅谈润乾报表与QlikView对比
  12. 2023最新SSM计算机毕业设计选题大全(附源码+LW)之java在线电影院售票系统5u8st
  13. Keyphrase Chunking - bert2chunk_dataloader.py分析
  14. 复合选择器之后代选择器
  15. 【1.01】VBA基础
  16. 百度图神经网络7日打卡营--DAY01前半部分 总结
  17. linux 搜狗拼音输入法
  18. 数仓工具—Hive实战之拉链表(3)
  19. 北京新生儿医保办理流程【非京籍】
  20. 一个程序员老总的年终总结2010版 1

热门文章

  1. 利用“应用分身”进行定位
  2. 毕业设计-基于微信小程序的校园“微警务”系统
  3. Happy Matt Friends
  4. 【算法】判断是否是素数isPrime() C++实现
  5. 规模比例缩放的极限和困局
  6. WordPress博客程序建站 安装教程
  7. 计算机项目(毕设课设) 之 含文档+PPT+源码等]精品基于PHP实现的网上买卖管理系统购物商城
  8. python批量生成图片_python图像处理-批量生成纯色图片
  9. 【原创】彼得德鲁克《管理的实践》札记(四)
  10. 【Windows】解决windows系统时间与北京时间相差8小时