SDN实验---Ryu的应用开发(二)流量监控

这篇具有很好参考价值的文章主要介绍了SDN实验---Ryu的应用开发(二)流量监控。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一:实现流量监控

        掌握基于Ryu开发流量监控应用: 主动下发逻辑

   (一)流量监控原理

控制器向交换机周期下发获取统计消息,请求交换机信息端口流量统计信息
请求流表项统计信息(提高)
根据交换机统计信息计算计算流量信息
流速公式: speed = (s(t1) - s(t0))/(t1-t0)
剩余带宽公式: free_bw = capability - speed
其中控制器向交换机周期下发获取统计消息,请求交换机消息------是主动下发过程
流速公式:是(t1时刻的流量-t0时刻的流量)/(t1-t0)
剩余带宽公式:链路总带宽-流速--------是这一个这一个,
例如s2-s3(不是一条,例如:h1->s1->s2->s3->h2)的剩余带宽
路径有效带宽是只:这一整条路径中,按照最小的剩余带宽处理

SDN实验---Ryu的应用开发(二)流量监控

二:代码实现     

from operator import attrgetter

from ryu.app import simple_switch_13
from ryu.controller.handler import set_ev_cls
from ryu.controller import ofp_event
from ryu.controller.handler import MAIN_DISPATCHER,DEAD_DISPATCHER
from ryu.lib import hub

class MyMonitor(simple_switch_13.SimpleSwitch13):    #simple_switch_13 is same as the last experiment which named self_learn_switch
    '''
    design a class to achvie managing the quantity of flow
    '''

    def __init__(self,*args,**kwargs):
        super(MyMonitor,self).__init__(*args,**kwargs)
        self.datapaths = {}
        #use gevent to start monitor
        self.monitor_thread = hub.spawn(self._monitor)

    @set_ev_cls(ofp_event.EventOFPStateChange,[MAIN_DISPATCHER,DEAD_DISPATCHER])
    def _state_change_handler(self,ev):
        '''
        design a handler to get switch state transition condition
        '''
        #first get ofprocotol info
        datapath = ev.datapath
        ofproto = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        #judge datapath`s status to decide how to operate
        if datapath.state == MAIN_DISPATCHER:    #should save info to dictation 
            if datapath.id not in self.datapaths:
                self.datapaths[datapath.id] = datapath
                self.logger.debug("Regist datapath: %16x",datapath.id)
        elif datapath.state == DEAD_DISPATCHER:    #should remove info from dictation
            if datapath.id in self.datapaths:
                del self.datapaths[datapath.id]
                self.logger.debug("Unregist datapath: %16x",datapath.id)


    def _monitor(self):
        '''
        design a monitor on timing system to request switch infomations about port and flow
        '''
        while True:    #initiatie to request port and flow info all the time
            for dp in self.datapaths.values():
                self._request_stats(dp)
            hub.sleep(5)    #pause to sleep to wait reply, and gave time to other gevent to request

    def _request_stats(self,datapath):
        '''
        the function is to send requery to datapath
        '''
        self.logger.debug("send stats reques to datapath: %16x for port and flow info",datapath.id)

        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        req = parser.OFPFlowStatsRequest(datapath)
        datapath.send_msg(req)

        req = parser.OFPPortStatsRequest(datapath, 0, ofproto.OFPP_ANY)
        datapath.send_msg(req)


    @set_ev_cls(ofp_event.EventOFPPortStatsReply,MAIN_DISPATCHER)
    def _port_stats_reply_handler(self,ev):
        '''
        monitor to require the port state, then this function is to get infomation for port`s info
        print("6666666666port info:")
        print(ev.msg)
        print(dir(ev.msg))
        '''
        body = ev.msg.body
        self.logger.info('datapath             port     '
                        'rx_packets            tx_packets'
                        'rx_bytes            tx_bytes'
                        'rx_errors            tx_errors'
                        )
        self.logger.info('---------------    --------'
                        '--------    --------'
                        '--------    --------'
                        '--------    --------'
                        )
        for port_stat in sorted(body,key=attrgetter('port_no')):
                self.logger.info('%016x %8x %8d %8d %8d %8d %8d %8d',
                    ev.msg.datapath.id,port_stat.port_no,port_stat.rx_packets,port_stat.tx_packets,
                    port_stat.rx_bytes,port_stat.tx_bytes,port_stat.rx_errors,port_stat.tx_errors
                        )


    @set_ev_cls(ofp_event.EventOFPFlowStatsReply,MAIN_DISPATCHER)
    def _flow_stats_reply_handler(self,ev):
        '''
        monitor to require the flow state, then this function is to get infomation for flow`s info
        print("777777777flow info:")
        print(ev.msg)
        print(dir(ev.msg))
        '''
        body = ev.msg.body

        self.logger.info('datapath             '
                        'in_port            eth_src'
                        'out_port            eth_dst'
                        'packet_count        byte_count'
                        )
        self.logger.info('---------------    '
                        '----    -----------------'
                        '----    -----------------'
                        '---------    ---------'
                        )
        for flow_stat in sorted([flow for flow in body if flow.priority==1],
                        key=lambda flow:(flow.match['in_port'],flow.match['eth_src'])):
                self.logger.info('%016x    %8x    %17s    %8x    %17s    %8d    %8d',
                    ev.msg.datapath.id,flow_stat.match['in_port'],flow_stat.match['eth_src'],
                    flow_stat.instructions[0].actions[0].port,flow_stat.match['eth_dst'],
                    flow_stat.packet_count,flow_stat.byte_count
                        )

        代码讲解:

1.class MyMonitor(simple_switch_13.SimpleSwitch13):
simple_switch_13.SimpleSwitch13是样例代码,其中实现了和我们上一次实验中,自学习交换机类似的功能
(稍微多了个关于交换机是否上传全部packet还是只上传buffer_id),所以我们直接继承,可以减少写代码时间
2.协程实现伪并发self.monitor_thread = hub.spawn(self._monitor)
    def __init__(self,*args,**kwargs):
        super(MyMonitor,self).__init__(*args,**kwargs)
        self.datapaths = {}
        #use gevent to start monitor
        self.monitor_thread = hub.spawn(self._monitor)
3.
@set_ev_cls(ofp_event.EventOFPStateChange,[MAIN_DISPATCHER,DEAD_DISPATCHER])
    def _state_change_handler(self,ev):
        '''
        design a handler to get switch state transition condition
        '''
        #first get ofprocotol info
        datapath = ev.datapath
        ofproto = datapath.ofproto
        ofp_parser = datapath.ofproto_parser

        #judge datapath`s status to decide how to operate
        if datapath.state == MAIN_DISPATCHER:    #should save info to dictation 
            if datapath.id not in self.datapaths:
                self.datapaths[datapath.id] = datapath
                self.logger.debug("Regist datapath: %16x",datapath.id)
        elif datapath.state == DEAD_DISPATCHER:    #should remove info from dictation
            if datapath.id in self.datapaths:
                del self.datapaths[datapath.id]
                self.logger.debug("Unregist datapath: %16x",datapath.id)

当交换机状态发生变化时,会触发该事件处理函数。该函数首先获取事件中的datapath信息,并判断datapath的状态是MAIN_DISPATCHER还是DEAD_DISPATCHER。

如果datapath的状态是MAIN_DISPATCHER,说明该交换机已经连接到控制器,需要将其信息保存到控制器的datapahts字典中。如果该交换机的id已经存在于datapahts字典中,则不需要再次保存。最后打印调试信息,表示已经成功注册该datapath。

如果datapath的状态是DEAD_DISPATCHER,说明该交换机已经从控制器中断开连接,需要将其信息从datapahts字典中删除。如果该交换机的id已经不存在于datapahts字典中,则不需要再次删除。最后打印调试信息,表示已经成功注销该datapath。
4.在协程中实现周期请求交换机信息
    def _monitor(self):
        '''
        design a monitor on timing system to request switch infomations about port and flow
        '''
        while True:    #initiatie to request port and flow info all the time
            for dp in self.datapaths.values():
                self._request_stats(dp)
            hub.sleep(5)    #pause to sleep to wait reply, and gave time to other gevent to request
5.主动下发消息,请求交换机信息OFPFlowStatsRequest
注意:我们这里请求两个(端口和协议信息),所以我们要使用两个函数来分别处理port和flow响应

    def _request_stats(self,datapath):
        '''
        the function is to send requery to datapath
        '''
        self.logger.debug("send stats reques to datapath: %16x for port and flow info",datapath.id)
        ofproto = datapath.ofproto
        parser = datapath.ofproto_parser

        req = parser.OFPFlowStatsRequest(datapath)
        datapath.send_msg(req)

        req = parser.OFPPortStatsRequest(datapath, 0, ofproto.OFPP_ANY)  #可以向上面一样省略默认参数
        datapath.send_msg(req)
6.获取端口响应信息ofp_event.EventOFPPortStatsReply
@set_ev_cls(ofp_event.EventOFPPortStatsReply,MAIN_DISPATCHER)
    def _port_stats_reply_handler(self,ev):
        '''
        monitor to require the port state, then this function is to get infomation for port`s info
        print("6666666666port info:")
        print(ev.msg)
        print(dir(ev.msg))
        '''
        body = ev.msg.body
        self.logger.info('datapath             port     '
                        'rx_packets            tx_packets'
                        'rx_bytes            tx_bytes'
                        'rx_errors            tx_errors'
                        )
        self.logger.info('---------------    --------'
                        '--------    --------'
                        '--------    --------'
                        '--------    --------'
                        )
        for port_stat in sorted(body,key=attrgetter('port_no')):
                self.logger.info('%016x %8x %8d %8d %8d %8d %8d %8d',
                    ev.msg.datapath.id,port_stat.port_no,port_stat.rx_packets,port_stat.tx_packets,
                    port_stat.rx_bytes,port_stat.tx_bytes,port_stat.rx_errors,port_stat.tx_errors
                        )
7.获取flow协议响应信息ofp_event.EventOFPFlowStatsReply
@set_ev_cls(ofp_event.EventOFPFlowStatsReply,MAIN_DISPATCHER)
    def _flow_stats_reply_handler(self,ev):
        '''
        monitor to require the flow state, then this function is to get infomation for flow`s info
        print("777777777flow info:")
        print(ev.msg)
        print(dir(ev.msg))
        '''
        body = ev.msg.body

        self.logger.info('datapath             '
                        'in_port            eth_src'
                        'out_port            eth_dst'
                        'packet_count        byte_count'
                        )
        self.logger.info('---------------    '
                        '----    -----------------'
                        '----    -----------------'
                        '---------    ---------'
                        )
        for flow_stat in sorted([flow for flow in body if flow.priority==1],
                        key=lambda flow:(flow.match['in_port'],flow.match['eth_src'])):
                self.logger.info('%016x    %8x    %17s    %8x    %17s    %8d    %8d',
                    ev.msg.datapath.id,flow_stat.match['in_port'],flow_stat.match['eth_src'],
                    flow_stat.instructions[0].actions[0].port,flow_stat.match['eth_dst'],
                    flow_stat.packet_count,flow_stat.byte_count
                        )

三:实验演示

        (一)开启Ryu

ryu-manager my_monitor.py

        (二)开启Mininet

sudo mn --topo=tree,2,2 --controller=remote --mac

         (三)Ryu显示结果

SDN实验---Ryu的应用开发(二)流量监控

SDN实验---Ryu的应用开发(二)流量监控

 文章来源地址https://www.toymoban.com/news/detail-506394.html

 

到了这里,关于SDN实验---Ryu的应用开发(二)流量监控的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 数据库应用与开发【实验题汇总】

    实验目的:掌握SQL Server Management Studio集成环境的构成和基本操作,熟悉服务器管理和基本操作,熟悉联机丛书与教程的使用。 实验步骤: (1)SQL Server Management Studio的启动和退出 1)启动SQL Server Management Studio 2)连接服务器选择 3)连接服务器的属性设置 4)身份验证选择

    2024年02月01日
    浏览(41)
  • Android移动应用开发——实验七——小鸭子报数(广播)

        掌握布局与控件的使用方法     掌握有序广播机制,根据广播接收者的优先级顺序接收广播     掌握广播拦截机制 通过合理布局来搭建界面,界面效果如下图所示。采用有序广播方式,将下方小鸭子优先级分别设置1000、800、600。 1、当点击大喇叭后弹出“有序

    2024年02月09日
    浏览(225)
  • 移动应用开发实验-内容提供者-ContentResolver的使用

    本人将所学和前人的成果和经验结合,仅供学习和参考!!! 本文大部分源码内容有清晰的注释,请认真阅读! 通过线性布局和相对布局来搭建通讯录界面,界面效果如下图所示。创建布局文件contact_item.xml、导入界面图片、放置界面控件、创建条目界面的背景文件。创建

    2024年02月08日
    浏览(52)
  • javaee实验:搭建maven+spring boot开发环境,开发“Hello,Spring Boot”应用

    在开发中,maven和spring都是非常常用、非常重要的管理工具和框架,今天就在这里使用idea进行环境的搭建和创建第一个spring程序 1.1maven是一个跨平台的项目管理工具(主要管理jar包) 1.2它是Apache的一个开源项目,主要服务于基于Java平台的项目构建、依赖管理和项目信息管理

    2024年02月05日
    浏览(60)
  • 【网络应用开发】实验2--JSP技术及应用(HTTP状态400错误的请求的解决方法)

    目录 JSP技术及应用预习报告 一、实验目的 二、实验原理 三、实验预习内容 JSP技术及应用实验报告 一、实验目的 二、实验要求 三、实验内容与步骤 1. 创建一个名为exp02的Web项目,创建并执行下面JSP页面,文件名为counter. jsp 2. errorPage属性和isErrorPage属性的使用。 高亮重点 

    2023年04月15日
    浏览(40)
  • javaweb实验:Java Web综合应用开发__基于MVC模式

    本实验的目的是让学生掌握Java Web开发的基本原理和方法,以及MVC设计模式的应用。MVC是一种将程序分为三个部分的设计模式,即模型(Model)、视图(View)和控制器(Controller)。模型负责封装数据和业务逻辑,视图负责展示用户界面,控制器负责接收用户请求并调用模型和

    2024年02月06日
    浏览(51)
  • Android移动应用开发——开灯与关灯(小兔子)——实验八——服务的启动与关闭

        掌握布局和基本控件的属性功能及使用方法     掌握startService()方法与stopService()方法启动和关闭服务 通过线性布局和相对布局来搭建一个界面,界面效果如下图所示。当点击“关灯”按钮后,转变到第二个状态。在第二个状态中,点击“开灯”按钮后,跳转回第一

    2024年02月05日
    浏览(56)
  • 移动应用开发实验一Android studio设计三种计算器的UI

    使用必要的布局方式,设计下面三种计算器的界面: 简单的计算器 科学计算器 程序计算器 边框的设置是建立一个drawable的xml文件,然后写了边框宽度、颜色、圆角和内边距。调用的时候用到了background属性 。

    2024年02月11日
    浏览(59)
  • 鸿蒙原生应用/元服务开发-延迟任务开发实现(二)

    接口名 接口描述 startWork(work: WorkInfo): void; 申请延迟任务 stopWork(work: WorkInfo, needCancel?: boolean): void; 取消延迟任务 getWorkStatus(workId: number, callback: AsyncCallback): void; 获取延迟任务状态(Callback形式) getWorkStatus(workId: number): Promise; 获取延迟任务状态(Promise形式) obtainAllWorks(callba

    2024年01月18日
    浏览(57)
  • 驱动开发:通过应用堆实现多次通信

    在前面的文章 《驱动开发:运用MDL映射实现多次通信》 LyShark教大家使用 MDL 的方式灵活的实现了内核态多次输出结构体的效果,但是此种方法并不推荐大家使用原因很简单首先内核空间比较宝贵,其次内核里面不能分配太大且每次传出的结构体最大不能超过 1024 个,而最终

    2024年02月05日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包