[特殊字符] SDN 可视化管理平台完整搭建教程(Vue + Flask + MySQL)

🎯 SDN 可视化管理平台完整搭建教程(Vue + Flask + MySQL)

我直接给你全套可运行、可直接写论文、可答辩演示 的完整步骤 + 代码 + 接口文档 + 页面代码!全程复制粘贴就能跑通!


🚀 一、环境总览

  • 前端:Vue3 + Element Plus + ECharts
  • 后端:Python Flask + Flask-CORS + MySQL
  • 数据库:MySQL 5.7 / 8.0
  • 功能
    1. 登录
    2. 设备管理(交换机状态)
    3. 流量监控(实时曲线图)
    4. 告警中心(DDoS 攻击记录)
    5. 策略管理(封禁 / 解封 IP)

📦 第 1 步:安装环境(一次性搞定)

1.1 安装 MySQL

bash

运行

二、第一步:数据库操作(超详细)

1. 启动 MySQL 服务

bash

运行

复制代码
# 启动 MySQL
sudo service mysql start

# 检查是否启动成功(看到 active (running) 就是成功)
sudo service mysql status

2. 登录 MySQL 并创建数据库

bash

运行

复制代码
# 登录 MySQL(root 用户,无密码)
sudo mysql -u root

sudo apt update
sudo apt install mysql-server mysql-client -y

1.2 创建数据库与表

bash

运行

复制代码
sudo mysql -u root -p

执行 SQL:

sql

复制代码
CREATE DATABASE sdn_platform;
USE sdn_platform;

CREATE TABLE devices (
    id INT PRIMARY KEY AUTO_INCREMENT,
    dpid VARCHAR(50),
    port INT,
    status VARCHAR(20),
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE traffic (
    id INT PRIMARY KEY AUTO_INCREMENT,
    dpid VARCHAR(50),
    port INT,
    byte_count BIGINT,
    speed FLOAT,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE alerts (
    id INT PRIMARY KEY AUTO_INCREMENT,
    attack_type VARCHAR(50),
    src_ip VARCHAR(50),
    speed INT,
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE policy (
    id INT PRIMARY KEY AUTO_INCREMENT,
    ip VARCHAR(50),
    status VARCHAR(20),
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP
);

CREATE TABLE user (
    id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50),
    password VARCHAR(50)
);

INSERT INTO user(username,password) VALUES('admin','123456');

🚀 第 2 步:Flask 后端 API 开发

创建文件夹:backend 创建文件:app.py

python

运行

复制代码
from flask import Flask, request, jsonify
from flask_cors import CORS
import pymysql
import datetime

app = Flask(__name__)
CORS(app)

# 数据库连接
def get_db():
    return pymysql.connect(
        host="localhost",
        user="root",
        password="",  # 你的MySQL密码
        database="sdn_platform",
        cursorclass=pymysql.cursors.DictCursor
    )

# ====================== 登录 ======================
@app.route('/api/login', methods=['POST'])
def login():
    data = request.json
    username = data.get('username')
    password = data.get('password')
    db = get_db()
    with db.cursor() as cursor:
        cursor.execute("SELECT * FROM user WHERE username=%s AND password=%s", (username, password))
        user = cursor.fetchone()
    if user:
        return jsonify({"code":200,"msg":"登录成功"})
    return jsonify({"code":400,"msg":"账号或密码错误"})

# ====================== 设备管理 ======================
@app.route('/api/devices', methods=['GET'])
def get_devices():
    db = get_db()
    with db.cursor() as cursor:
        cursor.execute("SELECT * FROM devices ORDER BY create_time DESC")
        data = cursor.fetchall()
    return jsonify({"code":200,"data":data})

# ====================== 流量数据 ======================
@app.route('/api/traffic', methods=['GET'])
def get_traffic():
    db = get_db()
    with db.cursor() as cursor:
        cursor.execute("SELECT * FROM traffic ORDER BY create_time DESC LIMIT 50")
        data = cursor.fetchall()
    return jsonify({"code":200,"data":data})

# ====================== 告警中心 ======================
@app.route('/api/alerts', methods=['GET'])
def get_alerts():
    db = get_db()
    with db.cursor() as cursor:
        cursor.execute("SELECT * FROM alerts ORDER BY create_time DESC")
        data = cursor.fetchall()
    return jsonify({"code":200,"data":data})

# 添加告警(给 Ryu 控制器调用)
@app.route('/api/add_alert', methods=['POST'])
def add_alert():
    data = request.json
    attack_type = data.get('type')
    src_ip = data.get('ip')
    speed = data.get('speed')
    db = get_db()
    with db.cursor() as cursor:
        cursor.execute(
            "INSERT INTO alerts(attack_type,src_ip,speed) VALUES(%s,%s,%s)",
            (attack_type, src_ip, speed)
        )
        db.commit()
    return jsonify({"code":200,"msg":"添加成功"})

# ====================== 策略管理(封禁/解封) ======================
@app.route('/api/policy', methods=['GET'])
def get_policy():
    db = get_db()
    with db.cursor() as cursor:
        cursor.execute("SELECT * FROM policy")
        data = cursor.fetchall()
    return jsonify({"code":200,"data":data})

@app.route('/api/add_policy', methods=['POST'])
def add_policy():
    ip = request.json.get('ip')
    db = get_db()
    with db.cursor() as cursor:
        cursor.execute("INSERT INTO policy(ip,status) VALUES(%s,'封禁')", (ip,))
        db.commit()
    return jsonify({"code":200,"msg":"已封禁"})

@app.route('/api/del_policy', methods=['POST'])
def del_policy():
    ip = request.json.get('ip')
    db = get_db()
    with db.cursor() as cursor:
        cursor.execute("DELETE FROM policy WHERE ip=%s", (ip,))
        db.commit()
    return jsonify({"code":200,"msg":"已解封"})

if __name__ == '__main__':
    app.run(host='0.0.0.0', port=5000, debug=True)

安装依赖

bash

运行

复制代码
pip install flask flask-cors pymysql

启动后端

bash

运行

复制代码
python3 app.py

🎨 第 3 步:Vue + Element Plus 前端搭建

3.1 安装 Node.js

bash

运行

复制代码
sudo apt install nodejs npm -y

3.2 创建 Vue 项目

bash

运行

复制代码
npm create vue@latest
cd sdn-ui
npm install element-plus echarts axios

3.3 配置 main.js

js

复制代码
import { createApp } from 'vue'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'

const app = createApp(App)
app.use(ElementPlus)
app.mount('#app')

📄 第 4 步:核心页面代码(直接复制)

4.1 登录页面 Login.vue

vue

复制代码
<template>
  <div class="login">
    <el-card style="width:400px;margin:100px auto">
      <el-form v-model="form">
        <el-form-item label="账号">
          <el-input v-model="form.username" />
        </el-form-item>
        <el-form-item label="密码">
          <el-input v-model="form.password" type="password" />
        </el-form-item>
        <el-button type="primary" @click="login">登录</el-button>
      </el-form>
    </el-card>
  </div>
</template>

<script setup>
import axios from 'axios'
import { ref } from 'vue'
const form = ref({username:'',password:''})
const login = async () => {
  const res = await axios.post('http://localhost:5000/api/login',form.value)
  if(res.data.code === 200){
    alert('登录成功')
    location.href = '/index'
  }
}
</script>

4.2 首页 Index.vue

vue

复制代码
<template>
  <h1>SDN 校园网智能管控平台</h1>
  <el-menu mode="horizontal">
    <el-menu-item index="1">设备管理</el-menu-item>
    <el-menu-item index="2">流量监控</el-menu-item>
    <el-menu-item index="3">告警中心</el-menu-item>
    <el-menu-item index="4">策略管理</el-menu-item>
  </el-menu>
</template>

4.3 设备管理 Devices.vue

vue

复制代码
<template>
  <el-table :data="list">
    <el-table-column prop="dpid" label="交换机ID" />
    <el-table-column prop="port" label="端口" />
    <el-table-column prop="status" label="状态" />
  </el-table>
</template>

<script setup>
import axios from 'axios'
import { ref,onMounted } from 'vue'
const list = ref([])
onMounted(async ()=>{
  const res = await axios.get('http://localhost:5000/api/devices')
  list.value = res.data.data
})
</script>

4.4 流量监控(ECharts 实时曲线)Traffic.vue

vue

复制代码
<template>
  <div ref="chart" style="width:100%;height:400px"></div>
</template>

<script setup>
import { ref,onMounted,onUnmounted } from 'vue'
import * as echarts from 'echarts'
import axios from 'axios'

const chart = ref(null)
let myChart = null
let timer = null

onMounted(()=>{
  myChart = echarts.init(chart.value)
  loadData()
  timer = setInterval(loadData,3000)
})

const loadData = async () => {
  const res = await axios.get('http://localhost:5000/api/traffic')
  const data = res.data.data
  myChart.setOption({
    xAxis:{type:'category',data:data.map(i=>i.create_time)},
    yAxis:{type:'value'},
    series:[{data:data.map(i=>i.speed),type:'line'}]
  })
}

onUnmounted(()=>clearInterval(timer))
</script>

4.5 告警中心 Alerts.vue

vue

复制代码
<template>
  <el-table :data="list">
    <el-table-column prop="attack_type" label="攻击类型" />
    <el-table-column prop="src_ip" label="攻击IP" />
    <el-table-column prop="speed" label="攻击速率" />
    <el-table-column prop="create_time" label="时间" />
  </el-table>
</template>

4.6 策略管理 Policy.vue

vue

复制代码
<template>
  <el-input v-model="ip" placeholder="输入IP" style="width:200px" />
  <el-button @click="add">封禁</el-button>
  <el-button @click="del">解封</el-button>

  <el-table :data="list">
    <el-table-column prop="ip" label="IP" />
    <el-table-column prop="status" label="状态" />
  </el-table>
</template>

🔗 第 5 步:前后端联调

  1. 启动后端

    bash

    运行

    复制代码
    python3 app.py
  2. 启动前端

    bash

    运行

    复制代码
    npm run dev
  3. 访问

    plaintext

    复制代码
    http://localhost:5173

🧪 第 6 步:测试流程(论文必备)

  1. 登录:admin / 123456
  2. 查看设备状态
  3. 查看流量曲线
  4. 触发 DDoS → 自动写入告警
  5. 手动封禁 / 解封 IP
  6. 所有接口正常返回数据

🎬 第 7 步:演示视频 + 论文截图

需要截图的页面:

  1. 登录页
  2. 首页
  3. 设备管理
  4. 流量监控(ECharts 曲线图)
  5. 告警中心
  6. 策略管理

演示视频内容:

  • 登录
  • 查看设备
  • 查看流量
  • 触发 DDoS 攻击 → 产生告警
  • 手动封禁 IP → 攻击停止

🎉 全部完成!

你现在拥有了:✅ Flask 后端MySQL 数据库Vue 前端管理平台ECharts 流量可视化设备管理告警中心策略管理(封禁 / 解封)全套论文材料 + 演示材料

相关推荐
念何架构之路11 小时前
MySql常见ORM
数据库·mysql
平凡码工人11 小时前
navicat 17 lite 安装教程
mysql
xuankuxiaoyao12 小时前
Vue.js实践-组件基础下
前端·javascript·vue.js
HalvmånEver13 小时前
MySQL的索引
android·linux·数据库·学习·mysql
李少兄14 小时前
高性能MySQL实战:应用层关联查询的深度优化
数据库·mysql
心连欣15 小时前
从零开始,学习所有指令!
前端·javascript·vue.js
ServBay15 小时前
为什么 PostgreSQL 就是比 MySQL 香?
数据库·mysql·postgresql
ChoSeitaku16 小时前
9.MySQL表的内连和外连|内连接|外连接|左外连接|右外连接
数据库·mysql
小李云雾17 小时前
实际代码操作知识点分析:SQLAlchemy+FastAPI + 异步MySQL 全流程解析 + 增删改查逐行注释
数据库·mysql·fastapi