SDSN:基于SDN的卫星网络 您所在的位置:网站首页 sdn三个主要特征 SDSN:基于SDN的卫星网络

SDSN:基于SDN的卫星网络

2023-07-01 02:44| 来源: 网络整理| 查看: 265

SDSN:基于SDN的卫星网络

前段时间一直在做跟SDN与卫星网络相关的毕设,学习了很多东西也走了很多弯路,所以想分享一下自己的学习过程,并且对相关的知识做一个总结。

思路框架 相关知识获取:

关于SDSN网上的开源资料都十分有限,卫星方面基本上都是看的各种论文中怎么对卫星进行的构建,实现上也基本就简单的参考了STK工具包的使用,SDN方面开源的资料比较多,主要是SDNLAB,李呈的博客以及RYU Book,还有市面上能够买到的一些SDN的书籍。 整体的实现思路:利用STK等工具对卫星整体架构进行设计和仿真从而形成卫星网络的实验环境。 利用python的网络传输将STK构建的仿真环境传输给虚拟机,在虚拟机中利用接收到的仿真数据(可以为json格式)在Mininet(常用的SDN网络仿真工具)中构建SDN网络拓扑,最终在Mininet中连接到自己使用的控制器从而进行各种仿真实验。

下面大致的列举一些参考的资料: 关于卫星方面:

https://blog.csdn.net/qq_43901693/category_10245394.html Python与STK的联合仿真

关于SDN方面的:

李呈的博客:http://www.muzixing.com/index4.html SDN基础教程: https://space.bilibili.com/508139652 https://www.bilibili.com/video/BV1ft4y1a7ip/?spm_id_from=333.999.0.0 SDNLAB:https://www.sdnlab.com/20370.html 使用RYU进行的多种实验:https://blog.csdn.net/qq_41422448/category_11474633.html SDN相关的书籍: https://www.zhihu.com/pub/reader/119637507/chapter/1167046161537064960 RYU的源码解析:https://www.jianshu.com/p/ff59c7c5f056 RYU API: https://ryu.readthedocs.io/en/latest/api_ref.html

研究过程

完成整个研究任务需要大致了解一下几个方面:

卫星网络是如何构建的,他有怎么样的参数,轨道是什么样的,卫星是如何运动的,星体模型是什么样的?例如一个常见的铱星(Iridium)系统。SDN是一个什么样的概念,他的应用场景和关键技术是怎么样的?他在卫星网络中又是如何被使用的?SDN控制器与交换器各个是什么样的概念,是如何实现如何应用的。OpenFlow协议又是什么概念?在SDSN(Sat+SDN)的场景中,卫星与SDN是如何相互配合相互实现的?目前的研究领域和研究目标有哪些?技术难点和应用创新点有哪些?针对上述知识,如何在技术上进行仿真与实现? 天体网络架构

整体工作可以大致切分为两块:系统架构(实验环境(当然也有可能是研究内容))+ SDN 系统架构大致可以分为几个部分:

1.网络层次关系设计

在这里插入图片描述 网络层次关系我个人的理解好像就是嘴上说说,大致就是整个系统应该是三个层面的事情,这里不提太多。

2.网络运行机制设计

运行机制是一个相对复杂的概念。设计到组网和控制域划分的问题,有很多不同的设计方向。

https://www.sdnlab.com/15853.html

这里就直接用一下别人论文里的定义: 在这里插入图片描述 在这里插入图片描述

3.卫星星体星座设计

卫星星座则是一个比较复杂的部分,常常通过覆盖性分析来确定整个的卫星星体结构。其构建过程可以参考铱星(Iridium)系统或者Walker星座。 例如:Starklink SpaceX最初向FCC提交的报告里,Starlink是由4425颗分布在1100km高度轨道的LEO星座和7518颗分布在340km左右的VLEO(甚低轨)星座构成。具体分布参见表1和表2的星座轨道。 在这里插入图片描述 2018年底SpaceX又向FCC提交了修改计划,4月26日FCC宣布批准SpaceX调低其宽带星座项目部分卫星轨道的请求。将原1600颗1150km轨道卫星调整为1584颗550km的轨道卫星。通过降低部分卫星轨道,它所需卫星总数将可减少16颗,并将能让信号时延低至15毫秒。同时这将改善空间环境的安全性,因为轨道调低后的卫星即便不带推进,也会在报废后5年内再入地球大气层。 在这里插入图片描述 Starlink首先将实现1584颗550km的轨道卫星布置,实际发射时,由于火箭推力不够,卫星初始入轨点定为440km,后由推进器爬升至550km。知道1584颗卫星分布在24个平面,便比较容易用Walker星座设计器仿真出星座设计了。

其设计步骤如下

1)通过Space-track网站TLE根数分析出初始60颗卫星的轨道平面;根据发射日期和轨道倾角可以确定Starlink初始发射的60颗卫星国际编号为19029A至19029BM,NORAD编号为44235U至44294U,下载根数,导入STK;通过report分析J2000坐标系轨道升交点赤经

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-L09SlS7n-1687513200531)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/b52c343b-649d-4f99-bbc9-cbcfc5f2f0d7/Untitled.png)]

2)设定种子卫星;本文以2019.05.27日根数分析结果,设定种子卫星历元及根数为:27 May 2019 06:14:00.000 UTC、半长轴6928.137(高度550km)、升交点赤经160°、轨道倾角53°、偏心率0°、其他轨道参数为0。为卫星添加传感器(Sensor),设定圆锥半角为44.85°,为后续覆盖分析做准备。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-K01fgAKJ-1687513200532)(https://s3-us-west-2.amazonaws.com/secure.notion-static.com/408da770-148c-4627-aa5f-a412622c519c/Untitled.png)]

3)由种子卫星生成参数(T/P/F)24/66/1的Walker星座,这里参数F暂取为1,具体应该怎么设置最优我没有搞明白,STK有Parametric Study Tool STK模块,但我没找到,如有了解者,敬请指导。这里为了美观,可以设置名称显示及轨道曲线等参数,不详细说明,注意为了后续分析方便,最好勾选创建星座,因为接下来覆盖分析可以通过星座选定分析卫星或是传感器,选择的时候种子卫星或其传感器不要选进去。同时算1584个目标计算机压力还是有点大的,试算可以使用较小规模的参数,比如(T/P/F)4/4/1 在这里插入图片描述

4.卫星网络拓扑设计

最后就是网络拓扑设计,在卫星星体确定的情况下,如何实现之前的卫星运行机制以及层次关系。简单来说,就是如何将SDN比较好的引入到设计的卫星星体上来。 目前有多种架构方式,参考如下: 在这里插入图片描述 例如设计一个两层的卫星网络: 在这里插入图片描述如上图所示,LEO同样采用钵星体系,在LEO层面布置交换机,在MEO/GEO层面采用控制器部署 在地面控制中心部署控制器和MEO卫星来组成控制平面,为了简化网络模型,我们从逻辑上将多个地面控制中心视为一个整体的实体。LEO卫星层作为整个网络的基础设施层,负责数据包的转发。最初,每颗LEO卫星向其MEO卫星发送一个流表请求。MEO卫星在接收到流量表请求后,将收集到的信息发送到地面控制中心。地面控制中心计算不同的路由规则。 在这里插入图片描述 同样还有如上结构,采用了单一的控制器布置在GEO与全局相连,GEO层布置转发路由器承担部分转发功能,地面站则作为网络流量的输入层。

技术实现

在技术实现上,我主要参考了以下文章:

https://zhuanlan.zhihu.com/p/260657677 https://zhuanlan.zhihu.com/p/260657677)https://zhuanlan.zhihu.com/p/68385977 https://www.notion.so/SDN_SAT-79ebbc4f8aee4666a6b3b1208c683b21?pvs=4#9a4e85019d8a48cd9c62edd0ba0c0328

下面给出一段STK的单层结构与三层架构的参考代码,其中并没有具体给出LEO,MEO,GEO层的连接关系

import time import json from tqdm import tqdm startTime = time.time() from comtypes.gen import STKObjects, STKUtil, AgStkGatorLib from comtypes.client import CreateObject, GetActiveObject, GetEvents, CoGetObject, ShowEvents import requests import time """ SET TO TRUE TO USE ENGINE, FALSE TO USE GUI """ useStkEngine = True Read_Scenario = False ############################################################################ # Scenario Setup ############################################################################ if useStkEngine: # Launch STK Engine print("Launching STK Engine...") stkxApp = CreateObject("STKX11.Application") # Disable graphics. The NoGraphics property must be set to true before the root object is created. stkxApp.NoGraphics = True # Create root object stkRoot = CreateObject('AgStkObjects11.AgStkObjectRoot') else: # Launch GUI print("Launching STK...") if not Read_Scenario: uiApp = CreateObject("STK11.Application") else: uiApp = GetActiveObject("STK11.Application") uiApp.Visible = True uiApp.UserControl = True # Get root object stkRoot = uiApp.Personality2 # Set date format stkRoot.UnitPreferences.SetCurrentUnit("DateFormat", "UTCG") # Create new scenario print("Creating scenario...") if not Read_Scenario: # stkRoot.NewScenario('Kuiper') stkRoot.NewScenario('StarLink') scenario = stkRoot.CurrentScenario scenario2 = scenario.QueryInterface(STKObjects.IAgScenario) scenario2.StartTime = '24 Sep 2020 16:00:00.00' scenario2.StopTime = '25 Sep 2020 16:20:00.00' dt='24 Sep 2020 16:00:00' ts = int(time.mktime(time.strptime(dt, "%d %b %Y %H:%M:%S"))) totalTime = time.time() - startTime print("---Total time: {b:4.3f} sec ---".format(b=totalTime)) # 创建星座 def Creat_satellite(numOrbitPlanes=72, numSatsPerPlane=22, hight=550, Inclination=53, name='node_'): # Create constellation object print("--- create satellite ,total num :{a} ---".format(a=numOrbitPlanes * numSatsPerPlane)) constellation = scenario.Children.New(STKObjects.eConstellation, name) constellation2 = constellation.QueryInterface(STKObjects.IAgConstellation) # Insert the constellation of Satellites for orbitPlaneNum in range(numOrbitPlanes): # RAAN in degrees print("---create sat on orbitPlane {a} ---".format(a=orbitPlaneNum)) for satNum in range(numSatsPerPlane): # trueAnomaly in degrees # Insert satellite satellite = scenario.Children.New(STKObjects.eSatellite, f"{name}{orbitPlaneNum}-{satNum}") satellite2 = satellite.QueryInterface(STKObjects.IAgSatellite) # Select Propagator satellite2.SetPropagatorType(STKObjects.ePropagatorTwoBody) # Set initial state twoBodyPropagator = satellite2.Propagator.QueryInterface(STKObjects.IAgVePropagatorTwoBody) keplarian = twoBodyPropagator.InitialState.Representation.ConvertTo( STKUtil.eOrbitStateClassical).QueryInterface(STKObjects.IAgOrbitStateClassical) #定义半轴长度 keplarian.SizeShapeType = STKObjects.eSizeShapeSemimajorAxis #定义高度 keplarian.SizeShape.QueryInterface( STKObjects.IAgClassicalSizeShapeSemimajorAxis).SemiMajorAxis = hight + 6371 # km #定义偏心率 keplarian.SizeShape.QueryInterface(STKObjects.IAgClassicalSizeShapeSemimajorAxis).Eccentricity = 0 keplarian.Orientation.Inclination = int(Inclination) # degrees 倾角 keplarian.Orientation.ArgOfPerigee = 0 # degrees 近地点 keplarian.Orientation.AscNodeType = STKObjects.eAscNodeRAAN RAAN = 360 / numOrbitPlanes * orbitPlaneNum keplarian.Orientation.AscNode.QueryInterface(STKObjects.IAgOrientationAscNodeRAAN).Value = RAAN # degrees keplarian.LocationType = STKObjects.eLocationTrueAnomaly trueAnomaly = 360 / numSatsPerPlane * satNum keplarian.Location.QueryInterface(STKObjects.IAgClassicalLocationTrueAnomaly).Value = trueAnomaly # Propagate satellite2.Propagator.QueryInterface(STKObjects.IAgVePropagatorTwoBody).InitialState.Representation.Assign( keplarian) satellite2.Propagator.QueryInterface(STKObjects.IAgVePropagatorTwoBody).Propagate() # Add to constellation object constellation2.Objects.AddObject(satellite) # 为每个卫星加上发射机和接收机 def Add_transmitter_receiver(sat_list): print("--- add transmitter and reciver for sat ---") for each in sat_list: Instance_name = each.InstanceName # new transmitter and receiver transmitter = each.Children.New(STKObjects.eTransmitter, "Transmitter_" + Instance_name) reciver = each.Children.New(STKObjects.eReceiver, "Reciver_" + Instance_name) #sensor = each.Children.New(STKObjects.eSensor, 'Sensor_' + Instance_name) # 设置发射机参数 def Set_Transmitter_Parameter(transmitter, frequency=12, EIRP=20, DataRate=14): transmitter2 = transmitter.QueryInterface(STKObjects.IAgTransmitter) # 建立发射机的映射,以便对其进行设置 transmitter2.SetModel('Simple Transmitter Model') txModel = transmitter2.Model txModel = txModel.QueryInterface(STKObjects.IAgTransmitterModelSimple) txModel.Frequency = frequency # GHz range:10.7-12.7GHz txModel.EIRP = EIRP # dBW txModel.DataRate = DataRate # Mb/sec # 设置接收机参数 def Set_Receiver_Parameter(receiver, GT=20, frequency=12): receiver2 = receiver.QueryInterface(STKObjects.IAgReceiver) # 建立发射机的映射,以便对其进行设置 receiver2.SetModel('Simple Receiver Model') recModel = receiver2.Model recModel = recModel.QueryInterface(STKObjects.IAgReceiverModelSimple) recModel.AutoTrackFrequency = False recModel.Frequency = frequency # GHz range:10.7-12.7GHz recModel.GOverT = GT # dB/K return receiver2 # 获得接收机示例,并设置其参数 def Get_sat_receiver(sat, GT=20, frequency=12): receiver = sat.Children.GetElements(STKObjects.eReceiver)[0] # 找到该卫星的接收机 receiver2 = Set_Receiver_Parameter(receiver=receiver, GT=GT, frequency=frequency) return receiver2 def get_time(): timeNow = time.strftime("%d %b %Y %H:%M:%S", time.localtime(ts)) timeNowLong = str(timeNow) + ".00" return timeNowLong # 计算传输链路 def Compute_access(access): # print("---computer access---") access.ComputeAccess() accessDP = access.DataProviders.Item('Link Information') accessDP2 = accessDP.QueryInterface(STKObjects.IAgDataPrvTimeVar) Elements = ["Range"] results = accessDP2.ExecSingleElements(get_time(), Elements) # results2 = accessDP2.ExecSingleElements(scenario2.StopTime, Elements) # Times = results.DataSets.GetDataSetByName('Time').GetValues() # 时间 # EbNo = results.DataSets.GetDataSetByName('Eb/No').GetValues() # 码元能量 # BER = results.DataSets.GetDataSetByName('BER').GetValues() # 误码率 # Link_Name = results.DataSets.GetDataSetByName('Link Name').GetValues() # Prop_Loss = results.DataSets.GetDataSetByName('Prop Loss').GetValues() # Xmtr_Gain = results.DataSets.GetDataSetByName('Xmtr Gain').GetValues() # EIRP = results.DataSets.GetDataSetByName('EIRP').GetValues() Range = results.DataSets.GetDataSetByName('Range').GetValues() # Range2=results2.DataSets.GetDataSetByName('Range').GetValues() # print(results2) return Range def Creating_All_Access(): # 首先清空场景中所有的链接 print('--- Clearing All Access ---') print('--- create Access ---') stkRoot.ExecuteCommand('RemoveAllAccess /') # 计算某个卫星与其通信的四颗卫星的链路质量,并生成报告 for each_sat in sat_list: now_sat_name = each_sat.InstanceName now_plane_num = int(now_sat_name.split('-')[0][5:]) now_sat_num = int(now_sat_name.split('-')[1]) now_sat_transmitter = each_sat.Children.GetElements(STKObjects.eTransmitter)[0] # 找到该卫星的发射机 Set_Transmitter_Parameter(now_sat_transmitter, EIRP=20) # 发射机与接收机相连 # 与后面的卫星的接收机相连 B_Name = sat_dic['node_' + str(now_plane_num) + '-' + str((now_sat_num + 1) % 10)].InstanceName F_Name = sat_dic['node_' + str(now_plane_num) + '-' + str((now_sat_num - 1) % 10)].InstanceName L_Name = sat_dic['node_' + str((now_plane_num - 1) % 10) + '-' + str(now_sat_num)].InstanceName R_Name = sat_dic['node_' + str((now_plane_num + 1) % 10) + '-' + str(now_sat_num)].InstanceName access_backward = now_sat_transmitter.GetAccessToObject( Get_sat_receiver(sat_dic['node_' + str(now_plane_num) + '-' + str((now_sat_num + 1) % 10)])) # 与前面的卫星的接收机相连 access_forward = now_sat_transmitter.GetAccessToObject( Get_sat_receiver(sat_dic['node_' + str(now_plane_num) + '-' + str((now_sat_num - 1) % 10)])) # 与左面的卫星的接收机相连 access_left = now_sat_transmitter.GetAccessToObject( Get_sat_receiver(sat_dic['node_' + str((now_plane_num - 1) % 10) + '-' + str(now_sat_num)])) # 与右面的卫星的接收机相连 access_right = now_sat_transmitter.GetAccessToObject( Get_sat_receiver(sat_dic['node_' + str((now_plane_num + 1) % 10) + '-' + str(now_sat_num)])) B_Range = Compute_access(access_backward) F_Range = Compute_access(access_forward) L_Range = Compute_access(access_left) R_Range = Compute_access(access_right) B_Dict = {'node1': now_sat_name, 'node2': B_Name, 'bw': 20, 'delay': str(int(B_Range[0] / 300))+'ms', 'jitter': '1ms', 'loss': 0} F_Dict = {'node1': now_sat_name, 'node2': F_Name, 'bw': 20, 'delay': str(int(F_Range[0] / 300))+'ms', 'jitter': '1ms','loss': 0} L_Dict = {'node1': now_sat_name, 'node2': L_Name, 'bw': 20, 'delay': str(int(L_Range[0] / 300))+'ms', 'jitter': '1ms', 'loss': 0} R_Dict = {'node1': now_sat_name, 'node2': R_Name, 'bw': 20, 'delay':str(int(R_Range[0] / 300))+'ms', 'jitter': '1ms', 'loss': 0} data_list.append(B_Dict) data_list.append(F_Dict) #data_list.append(L_Dict) #data_list.append(R_Dict) # print('{0}\r', B_Range, F_Range, L_Range, R_Range) # stkRoot.ExecuteCommand('RemoveAllAccess /') def Change_Sat_color(sat_list): # 修改卫星及其轨道的颜色 print('Changing Color of Satellite') for each_sat in sat_list: now_sat_name = each_sat.InstanceName now_plane_num = int(now_sat_name.split('_')[0][3:]) now_sat_num = int(now_sat_name.split('_')[1]) satellite = each_sat.QueryInterface(STKObjects.IAgSatellite) graphics = satellite.Graphics graphics.SetAttributesType(1) # eAttributesBasic attributes = graphics.Attributes attributes_color = attributes.QueryInterface(STKObjects.IAgVeGfxAttributesBasic) attributes_color.Inherit = False # 16436871 浅蓝色 # 2330219 墨绿色 # 42495 橙色 # 9234160 米黄色 # 65535 黄色 # 255 红色 # 16776960 青色 color_sheet = [16436871, 2330219, 42495, 9234160, 65535, 255, 16776960] if now_sat_name[2] == 'A': color = 255 elif now_sat_name[2] == 'B': color = 42495 elif now_sat_name[2] == 'C': color = 16436871 attributes_color.Color = color # 找出轨道对应的属性接口 orbit = attributes.QueryInterface(STKObjects.IAgVeGfxAttributesOrbit) orbit.IsOrbitVisible = False # 将轨道设置为不可见 def mid_link(): for each_sat in sat_list: now_sat_name = each_sat.InstanceName tmpparam={'node1': now_sat_name, 'node2': "mid1", 'bw': 20, 'delay': "20ms", 'jitter': '1ms', 'loss': 0} data_list.append(tmpparam) # 如果不是读取当前场景,即首次创建场景 if not Read_Scenario: Creat_satellite(numOrbitPlanes=10, numSatsPerPlane=10, hight=550, Inclination=53) # Starlink # Kuiper # Creat_satellite(numOrbitPlanes=34, numSatsPerPlane=34, hight=630, Inclination=51.9, name='KPA') # Phase A # Creat_satellite(numOrbitPlanes=32, numSatsPerPlane=32, hight=610, Inclination=42, name='KPB') # Phase B #Creat_satellite(numOrbitPlanes=28, numSatsPerPlane=28, hight=590, Inclination=33) # Phase C sat_list = stkRoot.CurrentScenario.Children.GetElements(STKObjects.eSatellite) Add_transmitter_receiver(sat_list) # 创建卫星的字典,方便根据名字对卫星进行查找 sat_list = stkRoot.CurrentScenario.Children.GetElements(STKObjects.eSatellite) sat_dic = {} data_list = [] print('--- Creating Satellite Dictionary ---') for sat in sat_list: sat_dic[sat.InstanceName] = sat Plane_num = [] for i in range(0, 10): Plane_num.append(i) Sat_num = [] for i in range(0, 10): Sat_num.append(i) headers = { "Content-Type": "application/json;charset=utf8" } for i in range(0,10): Creating_All_Access() ts+=600 print(data_list) data_list = json.dumps(data_list) response = requests.post('http://192.168.56.135:8000/modify/', data = data_list,headers=headers) print("--- topo uptade ---") data_list = [] if i==0: mid_link() data_list = json.dumps(data_list) print(data_list) response = requests.post('http://192.168.56.135:8000/modify/', data = data_list,headers=headers) print(i) time.sleep(30) print("end") def Creating_All_Access(): # 首先清空场景中所有的链接 print('--- Clearing All Access ---') print('--- create Access ---') stkRoot.ExecuteCommand('RemoveAllAccess /') # 计算某个卫星与其通信的四颗卫星的链路质量,并生成报告 for each_sat in sat_list: now_sat_name = each_sat.InstanceName print(now_sat_name) now_plane_num = int(now_sat_name.split('-')[0][4:]) now_sat_num = int(now_sat_name.split('-')[1]) now_plane_name = (now_sat_name.split(' ')[0][:4]) now_sat_transmitter = each_sat.Children.GetElements(STKObjects.eTransmitter)[0] # 找到该卫星的发射机 Set_Transmitter_Parameter(now_sat_transmitter, EIRP=20) # 发射机与接收机相连 # 与后面的卫星的接收机相连 if(now_plane_name == 'LEO_'): numOrbitPlanes = 6 numSatsPerPlane = 12 B_Name = sat_dic['LEO_' + str(now_plane_num) + '-' + str((now_sat_num + 1) % numSatsPerPlane)].InstanceName F_Name = sat_dic['LEO_' + str(now_plane_num) + '-' + str((now_sat_num - 1) % numSatsPerPlane)].InstanceName # L_Name = sat_dic['LEO_' + str((now_plane_num - 1) % numOrbitPlanes) + '-' + str(now_sat_num)].InstanceName # R_Name = sat_dic['LEO_' + str((now_plane_num + 1) % numOrbitPlanes) + '-' + str(now_sat_num)].InstanceName access_backward = now_sat_transmitter.GetAccessToObject( Get_sat_receiver(sat_dic['LEO_' + str(now_plane_num) + '-' + str((now_sat_num + 1) % numSatsPerPlane)])) # 与前面的卫星的接收机相连 access_forward = now_sat_transmitter.GetAccessToObject( Get_sat_receiver(sat_dic['LEO_' + str(now_plane_num) + '-' + str((now_sat_num - 1) % numSatsPerPlane)])) # 与左面的卫星的接收机相连 # access_left = now_sat_transmitter.GetAccessToObject( # Get_sat_receiver(sat_dic['node_' + str((now_plane_num - 1) % numOrbitPlanes) + '-' + str(now_sat_num)])) # 与右面的卫星的接收机相连 # access_right = now_sat_transmitter.GetAccessToObject( # Get_sat_receiver(sat_dic['node_' + str((now_plane_num + 1) % numOrbitPlanes) + '-' + str(now_sat_num)])) B_Range = Compute_access(access_backward) F_Range = Compute_access(access_forward) # L_Range = Compute_access(access_left) # R_Range = Compute_access(access_right) B_Dict = {'node1': now_sat_name, 'node2': B_Name, 'bw': 20, 'delay': str(int(B_Range[0] / 300)) + 'ms', 'jitter': '1ms', 'loss': 0} F_Dict = {'node1': now_sat_name, 'node2': F_Name, 'bw': 20, 'delay': str(int(F_Range[0] / 300)) + 'ms', 'jitter': '1ms', 'loss': 0} # L_Dict = {'node1': now_sat_name, 'node2': L_Name, 'bw': 20, 'delay': str(int(L_Range[0] / 300))+'ms', 'jitter': '1ms', # 'loss': 0} # R_Dict = {'node1': now_sat_name, 'node2': R_Name, 'bw': 20, 'delay':str(int(R_Range[0] / 300))+'ms', 'jitter': '1ms', # 'loss': 0} data_list.append(B_Dict) data_list.append(F_Dict) # data_list.append(L_Dict) # data_list.append(R_Dict) elif(now_plane_name == 'MEO_'): numOrbitPlanes = 3 numSatsPerPlane = 9 B_Name = sat_dic['MEO_' + str(now_plane_num) + '-' + str((now_sat_num + 1) % numSatsPerPlane)].InstanceName F_Name = sat_dic['MEO_' + str(now_plane_num) + '-' + str((now_sat_num - 1) % numSatsPerPlane)].InstanceName # L_Name = sat_dic['MEO_' + str((now_plane_num - 1) % numOrbitPlanes) + '-' + str(now_sat_num)].InstanceName # R_Name = sat_dic['MEO_' + str((now_plane_num + 1) % numOrbitPlanes) + '-' + str(now_sat_num)].InstanceName access_backward = now_sat_transmitter.GetAccessToObject( Get_sat_receiver(sat_dic['MEO_' + str(now_plane_num) + '-' + str((now_sat_num + 1) % numSatsPerPlane)])) # 与前面的卫星的接收机相连 access_forward = now_sat_transmitter.GetAccessToObject( Get_sat_receiver(sat_dic['MEO_' + str(now_plane_num) + '-' + str((now_sat_num - 1) % numSatsPerPlane)])) # 与左面的卫星的接收机相连 # access_left = now_sat_transmitter.GetAccessToObject( # Get_sat_receiver(sat_dic['MEO_' + str((now_plane_num - 1) % numOrbitPlanes) + '-' + str(now_sat_num)])) # 与右面的卫星的接收机相连 # access_right = now_sat_transmitter.GetAccessToObject( # Get_sat_receiver(sat_dic['MEO_' + str((now_plane_num + 1) % numOrbitPlanes) + '-' + str(now_sat_num)])) B_Range = Compute_access(access_backward) F_Range = Compute_access(access_forward) # L_Range = Compute_access(access_left) # R_Range = Compute_access(access_right) B_Dict = {'meo1': now_sat_name, 'meo2': B_Name, 'bw': 20, 'delay': str(int(B_Range[0] / 300)) + 'ms', 'jitter': '1ms', 'loss': 0} F_Dict = {'meo1': now_sat_name, 'meo2': F_Name, 'bw': 20, 'delay': str(int(F_Range[0] / 300)) + 'ms', 'jitter': '1ms', 'loss': 0} # L_Dict = {'meo1': now_sat_name, 'meo2': L_Name, 'bw': 20, 'delay': str(int(L_Range[0] / 300))+'ms', 'jitter': '1ms', # 'loss': 0} # R_Dict = {'meo1': now_sat_name, 'meo2': R_Name, 'bw': 20, 'delay':str(int(R_Range[0] / 300))+'ms', 'jitter': '1ms', # 'loss': 0} data_list.append(B_Dict) data_list.append(F_Dict) # data_list.append(L_Dict) # data_list.append(R_Dict) elif (now_plane_name == 'GEO_'): numOrbitPlanes = 3 numSatsPerPlane = 1 SDN

在SDN部分的研究则相当的广泛了,之前给到的参考资料中可以提供很多的借鉴,后续有时间的话会出一下自己对于RYU控制器的理解以及一些相关功能的实现。基础的知识也就不做太多介绍了。 这里主要分享一下STK与Mininet进行连接以及json数据传输: 大体思路就是利用Falsk将STK的卫星拓扑参数传递给Mininet,Mininet通过读取的轨道参数进行交换机与控制器的构建。以下的代码仅供参考,根据实际情况进行修改即可。

if __name__ == "__main__": setLogLevel("info") OVSKernelSwitch.setup() //开启一个网络 intfName_1 = "eth2" //将虚拟机eth2赋值给为变量intfName_1 intfName_3 = "eth3" info("****checking****", intfName_1, '\n') checkIntf(intfName_1) //检查是否可用 info("****checking****", intfName_3, '\n') checkIntf(intfName_3) info("****creating network****\n") net = Mininet(listenPort = 6633) //创建一个Mininet的实例,端口为6633 mycontroller = RemoteController("muziController", ip = "192.168.0.1")//创建远程控制器,ip=192.168.0.1,端口是6633。 switch_1 = net.addSwitch('s1') //在net里添加交换机s1,mininet中规则为:如果不填充dpid参数,则dpid参数默认取sn的n.即s1的dpid为1。 switch_2 = net.addSwitch('s2') switch_3 = net.addSwitch('s3') switch_4 = net.addSwitch('s4') net.controllers = [mycontroller] //将远程控制器添加到网络中 net.addLink(switch_1, switch_2, 2, 1)# node1, node2, port1, port2net.addLink(switch_2, switch_3, 2, 1)//将s2的2端口跟s3的1端口连接起来。(物理连接) net.addLink(switch_1, switch_4, 3, 1) //需要注意的是,以上连接的链路是一个环形的链路,在没有解决风暴的情况下,会出问题。 info("*****Adding hardware interface ", intfName_1, "to switch:" ,switch_1.name, '\n') info("*****Adding hardware interface ", intfName_3, "to switch:" ,switch_3.name, '\n') _intf_1 = Intf(intfName_1, node = switch_1, port = 1)//将intfName_1和s1的端口1相连,形成一个接口_intf_1 _intf_3 = Intf(intfName_3, node = switch_3, port = 2) net.addLink(switch_4, switch_3, 2, 3)//为什么放在这里呢?因为mininet中允许的端口分配方式是从小到大分配,所以,s3的3端口的配置应该放在s3的2端口之后,虽然难看,但是必须这么做,当然你也可以从新分配端口,只要保证端口是从小到大分配就好了。 info("Node: you may need to reconfigure the interfaces for the Mininet hosts:\n", net.hosts, '\n') net.start() //启动net CLI(net) //等待键入命令 net.stop() //关闭net # mininet/mininet/custom/modify_Link.py from mininet.net import Mininet from typing import Dict import time //对于当前node_n_m 得到node_(n+1)_(m+1) def get_next(n, m, n_max, m_max): n_ = (n+1)%n_max m_ = (m+1)%m_max return n_, m_ //修正Link,用于动态星体时需要修改链路情况时使用 def modifyLink(net:Mininet, node1:str, node2:str, params1:Dict, params2:Dict=None): """ 利用params1和params2设置属性连接node1和node2的连接的属性, params1控制node1对应的intf params2控制node2对应的intf,若缺省则通params1 参考 mininet.link.TCIntf.config() params1和params2的键值参考下面 for all Intf: mac=None, ip=None, ifconfig=None, up=True only for TCIntf: bw: bandwidth in b/s (e.g. '10m') delay: transmit delay (e.g. '1ms' ) jitter: jitter (e.g. '1ms') loss: loss (e.g. '1%' ) gro: enable GRO (False) txo: enable transmit checksum offload (True) rxo: enable receive checksum offload (True) speedup: experimental switch-side bw option use_hfsc: use HFSC scheduling use_tbf: use TBF scheduling latency_ms: TBF latency parameter enable_ecn: enable ECN (False) enable_red: enable RED (False) max_queue_size: queue limit parameter for netem """ h1 = net.getNodeByName( node1 ) h2 = net.getNodeByName( node2 ) links = h1.connectionsTo(h2) srcIntf = links[0][0] # todo 判断有没有写错 dstIntf = links[0][1] if not params2: #* 如果只修改node1,设置params2为非空字典,且不包含上面提到的参数 params2 = params1 srcIntf.config(**params1) dstIntf.config(**params2) def modifyNode(net:Mininet, node1:str, node2:str, params1:Dict): """ modify intf of node1 that is linked to node2 parameters are in modifyLink() for all Intf: mac=None, ip=None, ifconfig=None, up=True """ modifyLink(net, node1, node2, params1, params2=None) //设置ip_table def set_ip_table(net, node1, node2): h1 = net.getNodeByName( node1 ) h2 = net.getNodeByName( node2 ) links = h1.connectionsTo(h2) Intf1 = links[0][0] Intf2 = links[0][1] ip1 = Intf1.IP() ip2 = Intf2.IP() name1 = Intf1.name name2 = Intf2.name h1.cmd(f'ip r del 10.0.0.0/8 dev {name1}') # time.sleep(0.5) command = f'ip r add {ip2}/32 dev {name1} src {ip1}' h1.cmd(command) # time.sleep(0.5) print(f'{node1}--->{command}') h2.cmd(f'ip r del 10.0.0.0/8 dev {name2}') # time.sleep(0.5) command = f'ip r add {ip1}/32 dev {name2} src {ip2}' h2.cmd(command) print(f'{node2}--->{command}')

其中config文件:

```python n = 5 m = 5 # 同轨道默认参数 bw = 100 delay = '5ms' jitter = '1ms' loss = 0 # 与中继卫星默认参数 mid_bw = 100 mid_delay = '80ms' mid_jitter = '5ms' mid_loss = 0

对于SDN主要的也是两块:一是利用Mininet进行拓扑的创建,二是在自己选择的控制器上进行相关功能的设计与实现。



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有