mininet实验 动态改变转发规则实验
写在前面
- POX脚本设置好控制器的转发策略,所以只要理解脚本。
- mininet脚本设置好拓扑和相关信息,所以也只要理解脚本。
- POX脚本目前基本看不懂。
- 本实验我学会了:POX控制器Web界面,第一次真正的看到了流表项。
实验拓扑

- 在该环境下,假设H1 ping H4,初始的路由规则是S1-S2-S5,一秒后,路由转发规则变为S1-S3-S5,再过一秒,规则变为S1-S4-S5,然后再回到最初的转发规则S1-S2-S5。通过这个循环调度的例子动态地改变交换机的转发规则。
实验步骤
1.搭建环境
- 安装了mininet的虚拟机。
- 安装了pox的虚拟机。
2.创建脚本
- /pox目录下新建文件lab_controller.py,编辑其内容:
from pox.core import core
import pox.openflow.libopenflow_01 as of
from pox.lib.util import dpidToStr
from pox.lib.addresses import IPAddr, EthAddr
from pox.lib.packet.arp import arp
from pox.lib.packet.ethernet import ethernet, ETHER_BROADCAST
from pox.lib.packet.packet_base import packet_base
from pox.lib.packet.packet_utils import *
import pox.lib.packet as pkt
from pox.lib.recoco import Timer
import time
log = core.getLogger()
s1_dpid=0
s2_dpid=0
s3_dpid=0
s4_dpid=0
s5_dpid=0
s1_p1=0
s1_p4=0
s1_p5=0
s1_p6=0
s2_p1=0
s3_p1=0
s4_p1=0
pre_s1_p1=0
pre_s1_p4=0
pre_s1_p5=0
pre_s1_p6=0
pre_s2_p1=0
pre_s3_p1=0
pre_s4_p1=0
turn=0
def getTheTime(): #fuction to create a timestamp
flock = time.localtime()
then = "[%s-%s-%s" %(str(flock.tm_year),str(flock.tm_mon),str(flock.tm_mday))
if int(flock.tm_hour)<10:
hrs = "0%s" % (str(flock.tm_hour))
else:
hrs = str(flock.tm_hour)
if int(flock.tm_min)<10:
mins = str(flock.tm_min)
secs = "0%s" % (str(flock.tm_sec))
else:
secs = str(flock.tm_sec)
then +="]%s.%s.%s" % (hrs,mins,secs)
return then
def _timer_func ():
global s1_dpid, s2_dpid, s3_dpid, s4_dpid, s5_dpid,turn
#print getTheTime(), "sent the port stats request to s1_dpid"
if turn==0:
msg = of.ofp_flow_mod()
msg.command=of.OFPFC_MODIFY_STRICT
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.4"
msg.actions.append(of.ofp_action_output(port = 5))
core.openflow.getConnection(s1_dpid).send(msg)
turn=1
return
if turn==1:
msg = of.ofp_flow_mod()
msg.command=of.OFPFC_MODIFY_STRICT
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.4"
msg.actions.append(of.ofp_action_output(port = 6))
core.openflow.getConnection(s1_dpid).send(msg)
turn=2
return
if turn==2:
msg = of.ofp_flow_mod()
msg.command=of.OFPFC_MODIFY_STRICT
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.4"
msg.actions.append(of.ofp_action_output(port = 4))
turn=0
return
def _handle_portstats_received (event):
global s1_p1,s1_p4, s1_p5, s1_p6, s2_p1, s3_p1, s4_p1
global pre_s1_p1,pre_s1_p4, pre_s1_p5, pre_s1_p6, pre_s2_p1, pre_s3_p1, pre_s4_p1
if event.connection.dpid==s1_dpid:
for f in event.stats:
if int(f.port_no)<65534:
if f.port_no==1:
pre_s1_p1=s1_p1
s1_p1=f.rx_packets
if f.port_no==4:
pre_s1_p4=s1_p4
s1_p4=f.tx_packets
#s1_p4=f.tx_bytes
if f.port_no==5:
pre_s1_p5=s1_p5
s1_p5=f.tx_packets
if f.port_no==6:
pre_s1_p6=s1_p6
s1_p6=f.tx_packets
for f in event.stats:
if int(f.port_no)<65534:
if f.port_no==1:
pre_s2_p1=s2_p1
s2_p1=f.rx_packets
#s2_p1=f.rx_bytes
if event.connection.dpid==s3_dpid:
for f in event.stats:
if int(f.port_no)<65534:
if f.port_no==1:
pre_s3_p1=s3_p1
s3_p1=f.rx_packets
if event.connection.dpid==s4_dpid:
for f in event.stats:
if int(f.port_no)<65534:
if f.port_no==1:
pre_s4_p1=s4_p1
s4_p1=f.rx_packets
def _handle_ConnectionUp (event):
global s1_dpid, s2_dpid, s3_dpid, s4_dpid, s5_dpid
print "ConnectionUp: ",dpidToStr(event.connection.dpid)
#remember the connection dpid for switch
for m in event.connection.features.ports:
if m.name == "s1-eth1":
s1_dpid = event.connection.dpid
print "s1_dpid=", s1_dpid
elif m.name == "s2-eth1":
s2_dpid = event.connection.dpid
print "s2_dpid=", s2_dpid
elif m.name == "s3-eth1":
s3_dpid = event.connection.dpid
elif m.name == "s4-eth1":
s4_dpid = event.connection.dpid
print "s4_dpid=", s4_dpid
elif m.name == "s5-eth1":
s5_dpid = event.connection.dpid
print "s5_dpid=", s5_dpid
if s1_dpid<>0 and s2_dpid<>0 and s3_dpid<>0 and s4_dpid<>0:
Timer(1, _timer_func, recurring=True)
def _handle_PacketIn(event):
global s1_dpid, s2_dpid, s3_dpid, s4_dpid, s5_dpid
packet=event.parsed
if event.connection.dpid==s1_dpid:
a=packet.find('arp')
if a and a.protodst=="10.0.0.4":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=4))
event.connection.send(msg)
if a and a.protodst=="10.0.0.5":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=5))
event.connection.send(msg)
if a and a.protodst=="10.0.0.6":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=6))
event.connection.send(msg)
if a and a.protodst=="10.0.0.1":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=1))
event.connection.send(msg)
if a and a.protodst=="10.0.0.2":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=2))
event.connection.send(msg)
if a and a.protodst=="10.0.0.3":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=3))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.1"
msg.actions.append(of.ofp_action_output(port = 1))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.2"
msg.actions.append(of.ofp_action_output(port = 2))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.3"
msg.actions.append(of.ofp_action_output(port = 3))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 1
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.4"
msg.actions.append(of.ofp_action_output(port = 4))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.5"
msg.actions.append(of.ofp_action_output(port = 5))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.6"
msg.actions.append(of.ofp_action_output(port = 6))
event.connection.send(msg)
elif event.connection.dpid==s2_dpid:
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 1
msg.match.dl_type=0x0806
msg.actions.append(of.ofp_action_output(port = 2))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 1
msg.match.dl_type=0x0800
msg.actions.append(of.ofp_action_output(port = 2))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 2
msg.match.dl_type=0x0806
msg.actions.append(of.ofp_action_output(port = 1))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 2
msg.match.dl_type=0x0800
msg.actions.append(of.ofp_action_output(port = 1))
event.connection.send(msg)
elif event.connection.dpid==s3_dpid:
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 1
msg.match.dl_type=0x0806
msg.actions.append(of.ofp_action_output(port = 2))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 1
msg.match.dl_type=0x0800
msg.actions.append(of.ofp_action_output(port = 2))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 2
msg.match.dl_type=0x0806
msg.actions.append(of.ofp_action_output(port = 1))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 2
msg.match.dl_type=0x0800
msg.actions.append(of.ofp_action_output(port = 1))
event.connection.send(msg)
elif event.connection.dpid==s4_dpid:
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 1
msg.match.dl_type=0x0806
msg.actions.append(of.ofp_action_output(port = 2))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 1
msg.match.dl_type=0x0800
msg.actions.append(of.ofp_action_output(port = 2))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 2
msg.match.dl_type=0x0806
msg.actions.append(of.ofp_action_output(port = 1))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =10
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.in_port = 2
msg.match.dl_type=0x0800
msg.actions.append(of.ofp_action_output(port = 1))
event.connection.send(msg)
elif event.connection.dpid==s5_dpid:
a=packet.find('arp')
if a and a.protodst=="10.0.0.4":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=4))
event.connection.send(msg)
if a and a.protodst=="10.0.0.5":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=5))
event.connection.send(msg)
if a and a.protodst=="10.0.0.6":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=6))
event.connection.send(msg)
if a and a.protodst=="10.0.0.1":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=1))
event.connection.send(msg)
if a and a.protodst=="10.0.0.2":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=2))
event.connection.send(msg)
if a and a.protodst=="10.0.0.3":
msg = of.ofp_packet_out(data=event.ofp)
msg.actions.append(of.ofp_action_output(port=3))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.1"
msg.actions.append(of.ofp_action_output(port = 1))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.2"
msg.actions.append(of.ofp_action_output(port = 2))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.3"
msg.actions.append(of.ofp_action_output(port = 3))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.4"
msg.actions.append(of.ofp_action_output(port = 4))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.5"
msg.actions.append(of.ofp_action_output(port = 5))
event.connection.send(msg)
msg = of.ofp_flow_mod()
msg.priority =100
msg.idle_timeout = 0
msg.hard_timeout = 0
msg.match.dl_type = 0x0800
msg.match.nw_dst = "10.0.0.6"
msg.actions.append(of.ofp_action_output(port = 6))
event.connection.send(msg)
def launch ():
global start_time
core.openflow.addListenerByName("PortStatsReceived",_handle_portstats_received)
core.openflow.addListenerByName("ConnectionUp", _handle_ConnectionUp)
core.openflow.addListenerByName("PacketIn",_handle_PacketIn)
- 该脚本实现了动态转发策略。
- 我猜测基本思想应该是,基于时间来给交换机s1下发流表项。
- 在Mininet中创建文件mymininet.py。编辑其内容为:
#!/usr/bin/python
from mininet.topo import Topo
from mininet.net import Mininet
from mininet.node import CPULimitedHost
from mininet.link import TCLink
from mininet.util import dumpNodeConnections
from mininet.log import setLogLevel
from mininet.node import Controller
from mininet.cli import CLI
from functools import partial
from mininet.node import RemoteController
import os
class MyTopo(Topo):
"Single switch connected to n hosts."
def __init__(self):
Topo.__init__(self)
s1=self.addSwitch('s1')
s2=self.addSwitch('s2')
s3=self.addSwitch('s3')
s4=self.addSwitch('s4')
s5=self.addSwitch('s5')
h1=self.addHost('h1')
h2=self.addHost('h2')
h3=self.addHost('h3')
h4=self.addHost('h4')
h5=self.addHost('h5')
h6=self.addHost('h6')
self.addLink(h1, s1, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(h2, s1, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(h3, s1, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(s1, s2, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(s1, s3, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(s1, s4, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(s2, s5, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(s3, s5, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(s4, s5, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(s5, h4, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(s5, h5, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
self.addLink(s5, h6, bw=1, delay='10ms', loss=0, max_queue_size=1000, use_htb=True)
def perfTest():
"Create network and run simple performance test"
topo = MyTopo()
net = Mininet(topo=topo, host=CPULimitedHost, link=TCLink, controller=partial(RemoteController, ip='10.0.0.13', port=6633))
net.start()
print "Dumping host connections"
dumpNodeConnections(net.hosts)
h1,h2,h3=net.get('h1','h2','h3')
h4,h5,h6=net.get('h4','h5','h6')
h1.setMAC("0:0:0:0:0:1")
h2.setMAC("0:0:0:0:0:2")
h3.setMAC("0:0:0:0:0:3")
h4.setMAC("0:0:0:0:0:4")
h5.setMAC("0:0:0:0:0:5")
h6.setMAC("0:0:0:0:0:6")
CLI(net)
net.stop()
if __name__ == '__main__':
setLogLevel('info')
perfTest()
- 该脚本设置了拓扑。基本可以理解。
3.运行脚本
- /pox目录下运行脚本lab_controller.py
./pox.py lab_controller
- 在Mininet下运行脚本mymininet.py
chmod +x mymininet.py
./mymininet.py
- mininet终端信息

- POX控制器终端信息

- 现在我们通过h1向h4发包,来检测动态转发功能。
- 在mininet终端输入:
h1 ping -i 0.1 h4 #h1每秒向h4发10个包

- 这时在POX界面并没有出现有用的信息,反而是一些warning信息。

4.解决方案
- 既然在终端中没法看到发送的细节,我想到了Web界面。别的控制器都有UI界面POX也应该有吧?
- 我在一篇博客中找到了POX UI界面的实现方式:Poxdesk。
- 运行POX脚本时要想使用poxdesk必须多加一些参数,对于本实验运行lab_controller.py时,命令如下:
./pox.py lab_controller web messenger messenger.log_service messenger.ajax_transport openflow.of_service poxdesk
- 通用命令:
./pox.py 要运行的脚本 web messenger messenger.log_service messenger.ajax_transport openflow.of_service poxdesk
- 浏览器中输入:http://pox-ip:8000/poxdesk 来访问界面,其中pox-ip是本机IP地址。
- 进入Web界面后,我们打开s1的flowtable窗口。可以发现:对于目的是10.0.0.4(主机h4)的流表项在周期性变化,action中output端口在5,6之间切换。但是没有4(交换机s2),这个问题没有解决,可能是脚本本身的问题。


5.具体的连接图
- 通过mininet中的net命令可以得拓扑的详细信息,我简单的画了个示意图便于理解:

存在问题
- 端口切换时,为什么不能切换到s2?
mininet实验 动态改变转发规则实验的更多相关文章
- Mininet系列实验(六):Mininet动态改变转发规则实验
一. 实验目的 熟悉Mininet自定义拓扑脚本的编写:熟悉编写POX脚本动态改变转发规则 二.实验原理 在SDN环境中,控制器可以通过对交换机下发流表操作来控制交换机的转发行为.在本实验中,基于Mi ...
- Mininet实验 动态改变转发规则
介绍 拓扑如下: 在该环境下,假设H1 ping H4,初始的路由规则是S1-S2-S5,一秒后,路由转发规则变为S1-S3-S5,再过一秒,规则变为S1-S4-S5,然后再回到最初的转发规则S1-S ...
- SSH的本地、远程、动态端口转发实验笔记
SSH端口转发 SSH 会自动加密和解密所有 SSH 客户端与服务端之间的网络数据.但是,SSH 还能够将其他 TCP 端口的网络数据通过 SSH 链接来转发,并且自动提供了相应的加密及解密服务.这一 ...
- Mininet实验 基于Mininet实现BGP路径挟持攻击实验
参考:基于Mininet实现BGP路径挟持攻击实验 实验目的: 掌握如何mininet内模拟AS. 掌握BGP路径挟持的原理和分析过程. 实验原理: 互联网是由相互连接的自治系统AS组成的,通过一个通 ...
- 实验 4 :Open vSwitch 实验 —— Mininet 中使用 OVS 命令
实验 4 :Open vSwitch 实验 -- Mininet 中使用 OVS 命令 一.实验目的 Mininet 安装之后,会连带安装 Open vSwitch,可以直接通过 Python 脚本调 ...
- OpenDayLight Helium实验三 OpenDaylight二层转发机制实验 2
鉴于在个人笔记本上虚拟机运行ODL实在太慢,把实验的场景搬到了实验室. 实验上:OpenDayLight Helium实验三 OpenDaylight二层转发机制实验 抓包实验 紧接着,在运行Mini ...
- OpenDayLight Helium实验三 OpenDaylight二层转发机制实验
本文基于OpenDaylight二层转发机制实验 而成 在SDN网络中,处于末端的主机并不知道其连接的网络是SDN,某台主机要发送数据包到另一台主机,仍然需要进行IP到MAC地址的ARP解析.SDN网 ...
- 哈工大 计算机网络 实验三 IPv4 分组收发实验&IPv4 分组转发实验
计算机网络实验代码与文件可见github:计算机网络实验整理 实验名称 IPv4 分组收发实验&IPv4 分组转发实验 实验目的: (注:实验报告模板中的各项内容仅供参考,可依照实际实验情况进 ...
- 2017-2018-2 20155231《网络对抗技术》实验八: WEB基础实验
2017-2018-2 20155231<网络对抗技术>实验八:Web基础 实验要求: Web前端HTML(0.5分) 能正常安装.启停Apache.理解HTML,理解表单,理解GET与P ...
随机推荐
- 单片机中不带字库LCD液晶屏显示少量汉字
单片机中不带字库LCD液晶屏如何显示少量汉字,一般显示汉字的方法有1.使用带字库的LCD屏,2.通过SD 卡或者外挂spi flash存中文字库,3.直接将需要的汉字取模存入mcu的flash中. 第 ...
- Python学习手册之Python介绍、基本语法(一)
一.什么是python? python是一种高级的编程语言.它适合编写一些应用程序,比如:网站编程,脚本编程,科学计算和最近非常热门的AI(人工智能).目前,Google,腾讯,百度,阿里巴巴,豆瓣都 ...
- 字符编码——python学习
python学习—字符编码 例如汉字“中” 十进制:20013 二进制:01001110 00101101(unicode)/11100100 10111000 10101101(utf-8) 十六进 ...
- 1. 文件a.txt内容:每一行内容分别为商品名字,价钱,个数。
li = []with open('lo', encoding='utf-8', mode='r') as f1: for i in f1: l2=i.strip().split() dic = {' ...
- SQL宽字节注入
0x00 概述 - 什么是宽字节注入? 宽字节注入就是因为gbk编码方式需要两个ascii码组合来解码,所以形象的叫做宽字节,这个作为了解即可 -宽字节注入的条件 1) 数据库查询设置为GBK编码 2 ...
- Altium Designer (AD) 中规则的部分讲解
当创建好PCB时,选择 Design - Rules 即可进行规则的设置,也可以直接利用快捷键D-R(多利用快捷键,可以有效的提高设计效率,) 这个是规则的总界面,熟练以后可以直接从这里进行修改,很便 ...
- 基于visual studio 2017 以及cubemx 搭建stm32的开发环境(2)
主要解决 vs2017中,printf无法打印数据的问题. 在keil环境下正常使用printf功能,但是以下的重定向代码在vs2017下使用不了: #ifdef __GNUC__ /* With G ...
- kaggle之数据分析从业者用户画像分析
数据为kaggle社区发布的数据分析从业者问卷调查分析报告,其中涵盖了关于该行业不同维度的问题及调查结果.本文的目的为提取有用的数据,进行描述性展示.帮助新从业的人员更全方位地了解这个行业. 参考学习 ...
- 20155202 《Java程序设计》实验二(面向对象程序设计)实验报告
20155202 <Java程序设计>实验二(面向对象程序设计)实验报告 代码托管 实验内容 初步掌握单元测试和TDD 理解并掌握面向对象三要素:封装.继承.多态 初步掌握UML建模 熟悉 ...
- 20155229付钰涵-虚拟机安装及LINUX命令学习
安装Ubuntu遇到的问题 问题一: 新建虚拟电脑的版本只有32-bit,与老师所给教程中的64-bit不符.为此我上百度搜寻了答案. 第一种方法: 控制面板--程序与功能--启动或关闭windows ...