Flask初体验

这里有一份展示Flask与Python的协同代码,Flask的web页面展示了系统的一个暴露的公共tcp port连接的所有用户ip:port列表。

做完才发现没有什么用处,我的本意是做一个reverse的ssh或者telnet终端。看点有几个:

  1. 我原本是打算用multiprocessing.queue在python和Flask的web代码间交互,后来发现不必要。
  2. web客户处理的 app级变量最简单的方法是放在:app.config["<strkey>"]这个字典里。app变量如果更新记得要回写回去。
  3. python程序最好通过post方法,与Flask交互,更新app变量,例子中包含一个完整的示例:python post, flask response 
  4. web页面为了自动更新一些服务器变量,有一个自刷新的代码。
  5. 命令行可以主动切换web port和那个tcp port.

1.python: reverse_ssh_server.sh

import socket
import threading
from flask import Flask, render_template, jsonify, request
import requests
from sys import argv
import multiprocessing

TCP_PORT = 8888
WEB_PORT = 5000
CLIENT_MAX_LEN = 15

app= Flask(__name__, template_folder="./web") #, static_folder="./web"
connected_devices = []

# TCP服务器
def tcp_server():
    host = '0.0.0.0'
    port = TCP_PORT

    server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        server_socket.bind((host, port))
        server_socket.listen(15)
    except Exception as e:
        print(f"app port {port} bind error", e)
        return;

    print(f"TCP服务器已启动,监听端口 {port}...")

    while True:
        try:
            if(app is None): 
                continue;
            client_socket, addr = server_socket.accept()
            #print(f"连接来自 {addr}")
            if(len(connected_devices)>CLIENT_MAX_LEN):
                client_socket.close()
                continue
            json = {}
            json["dev"] = f"{addr}"
            dev_login(json)
            print(connected_devices)
        except Exception as e:
            print("client accept error.", e);
            server_socket.close();
            return;

def dev_login(dev_addr):
    url = f'http://localhost:{WEB_PORT}/api/devices/dev_login'
    headers = {'Content-Type': 'application/json'}
    response = requests.post(url, json=dev_addr, headers=headers)
    print("dev_login", response.json())  # 打印服务器返回的 JSON 响应

# Web页面
@app.route('/')
def index():
    connected_devices = app.config['connected_devices']
    return render_template('index.html', devices=connected_devices)

@app.route('/api/devices')
def get_device_list():
    connected_devices = app.config['connected_devices']
    # 这里应该是获取设备列表的逻辑,暂时用一个简单的列表代替
    # Assuming connected_devices is a multiprocessing.Queue
    ret = jsonify(connected_devices)
    print(ret)
    return ret

@app.route('/api/devices/dev_login', methods=['POST'])
def handle_post():
    # 获取 POST 请求中的 JSON 数据
    json_data = request.json["dev"]
    connected_devices = app.config['connected_devices']
    connected_devices.append(json_data);
    app.config['connected_devices'] = connected_devices
    # 在这里处理 JSON 数据,这里只是简单地返回接收到的 JSON 数据
    print("on_handle_post:", json_data, connected_devices)
    return jsonify(json_data)

if __name__ == '__main__':
    if len(argv)>=2:
        WEB_PORT = int(argv[1])
    if len(argv)>=3:
        TCP_PORT = int(argv[2])
    print(f"web port:{WEB_PORT}, tcp port:{TCP_PORT}")
    # 启动TCP服务器和Web应用
    app.config['connected_devices'] = connected_devices
    tcp_thread = threading.Thread(target=tcp_server)
    tcp_thread.start()
    app.run(debug=True, port=WEB_PORT)
    

2.web Flask使用的index.html

<!DOCTYPE html>
<html>
<head>
    <title>Device List</title>
</head>
<body>
    <h1>Device List</h1>
    <ul id="device-list">
        <!-- 设备列表将会动态添加到这里 -->
        <li>ip:port</li>
    </ul>

    <script>
        function updateDeviceList() {
            // 发送 AJAX 请求获取设备列表
            var xhr = new XMLHttpRequest();
            xhr.onreadystatechange = function() {
                if (xhr.readyState == XMLHttpRequest.DONE) {
                    if (xhr.status == 200) {
                        // 解析 JSON 响应
                        var devices = JSzeON.parse(xhr.responseText);
                        // 清空设备列表
                        document.getElementById("device-list").innerHTML = "";
                        // 遍历设备列表并添加到页面中
                        devices.forEach(function(device) {
                            var li = document.createElement("li");
                            li.textContent = device; //device.name
                            document.getElementById("device-list").appendChild(li);
                        });
                    }
                }
            };
            xhr.open("GET", "/api/devices", true);
            xhr.send();
        }
        
        // 页面加载时立即执行一次更新
        updateDeviceList();
        
        // 定时刷新,1秒执行一次
        setInterval(updateDeviceList, 1000);
    </script>
</body>
</html>

3.执行效果:

sudo -E python3.9 reverse_ssh_server.py 5000 3002

[sudo] root 的密码: 
web port:5000, tcp port:3002
TCP服务器已启动,监听端口 3002...
 * Serving Flask app 'reverse_ssh_server'
 * Debug mode: on
WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
 * Running on http://127.0.0.1:5000
Press CTRL+C to quit

4.进阶

4.1 Post 图片及其他参数给Flask

#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# 获取当前脚本文件所在目录的父目录,并构建相对路径
import os
import sys
current_dir = os.path.dirname(os.path.abspath(__file__))
project_path = os.path.join(current_dir, '..')
sys.path.append(project_path)
sys.path.append(current_dir)
import gpLog
import paho.mqtt.client as mqtt
from datetime import datetime
import cv2
import requests
import numpy as np

def gpWebPost_PostImage(url:str, cv2Image, ai_class:int):
    if not url.startswith("http://"):
        # 设置 POST 请求的 URL
        url = f'http://{url}'

    # 设置要发送的文件
    files = {
        'ai_snapshot': cv2Image  # 将文件打开为二进制模式
    }
    data = {
    'ai_class': 1,
    }

    jsonArg ={}
    jsonArg["ai_class"]=ai_class
    # 发送 POST 请求
    response = requests.post(url, files=files, json=jsonArg, data=data)

    # 检查响应
    if response.status_code == 200:
        return True
    else:
        return False

def gpWebPost_TestPostImage():
    # 读取图像
    url = "http://192.168.0.1:8080/aiimage/dev_0001/ch01"
    image = cv2.imread(r'/home/lubancat/图片/Rumelhart_rect.jpg')
    

    # 将图像转换为字节流
    _, img_encoded = cv2.imencode('.jpg', image)
    image_data = img_encoded.tobytes()
    gpWebPost_PostImage(url, image_data, 1)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/663253.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

音视频开发13 FFmpeg 音频 相关格式分析 -- AAC ADTS格式分析

这一节&#xff0c;我们学习常用的音频的格式 AAC&#xff0c;重点是掌握 AAC的传输格式 ADTS 头部的信息&#xff0c;目的是 &#xff1a; 当音频数据有问题的时候&#xff0c;如果是AAC的编码&#xff0c;在分析 头部信息的时候能够根据头部信息 判断问题是否出现在 头部。 A…

C++第二十二弹---vector深度剖析及模拟实现(下)

✨个人主页&#xff1a; 熬夜学编程的小林 &#x1f497;系列专栏&#xff1a; 【C语言详解】 【数据结构详解】【C详解】 目录 1、容量操作 2、内容修改操作 3、打印函数 4、迭代器失效 4.1、什么是迭代器失效 4.2、哪些操作会引起迭代器失效 总结 1、容量操作 size()…

【JAVA SE】多态

✨✨欢迎大家来到Celia的博客✨✨ &#x1f389;&#x1f389;创作不易&#xff0c;请点赞关注&#xff0c;多多支持哦&#x1f389;&#x1f389; 所属专栏&#xff1a;JAVA 个人主页&#xff1a;Celias blog~ 目录 引言 一、多态 1.1 多态的概念 1.2 多态的实现条件 1.3…

Python魔法之旅-魔法方法(05)

目录 一、概述 1、定义 2、作用 二、应用场景 1、构造和析构 2、操作符重载 3、字符串和表示 4、容器管理 5、可调用对象 6、上下文管理 7、属性访问和描述符 8、迭代器和生成器 9、数值类型 10、复制和序列化 11、自定义元类行为 12、自定义类行为 13、类型检…

微信小程序-网络数据请求(配置request合法域名)

1.小程序中网络数据请求的限制 出于安全方面的考虑&#xff0c;小程序官方对数据接口的请求做出了如下两个限制&#xff1a; &#xff08;1&#xff09;只能请求HTTPS类型的接口 &#xff08;2&#xff09;必须将接口的域名添加到信任列表中 如果要请求某个域名下的接口&am…

微信小程序发送订阅消息

小程序后台。订阅消息里面&#xff0c;新建一个消息模板 小程序代码&#xff0c;登录后&#xff0c;弹出订阅信息 requestSubscribeMessage: function () {wx.requestSubscribeMessage({tmplIds: [-323232-32323], // 替换为你的模板IDsuccess(res) {// 用户订阅结果console.l…

优化CPU占用率及内存占用2

在标准化无线通信板时&#xff0c;关注过程序占用ram的问题&#xff0c;当时 发现每一个线程都会分配8M栈空间&#xff0c;这次换rk3568后&#xff0c;偶尔看了下RAM占用&#xff0c;吓了一跳&#xff0c;不但每个线程有8M栈空间&#xff0c;几乎每个线程都占用了64MB的一个RAM…

多态--5.30

理解&#xff1a; 就是引用多个方法类&#xff1b; 方法可以加参数&#xff1b; 多态为方法的多态&#xff1b; 主要代码&#xff1a; // animal an; // cat c new cat(); // anc; //三行代码等于animal an new cat();#前提是要有animal类&…

【C语言回顾】预处理

前言1. 简单概要2. 预处理命令讲解结语 上期回顾: 【C语言回顾】编译和链接 个人主页&#xff1a;C_GUIQU 归属专栏&#xff1a;【C语言学习】 前言 各位小伙伴大家好&#xff01;上期小编给大家讲解了C语言中的编译和链接&#xff0c;接下来我们讲解一下预处理&#xff01; …

npm镜像源管理、nvm安装多版本node异常处理

查看当前使用的镜像源 npm config get registry --locationglobal 设置使用官方源 npm config set registry https://registry.npmjs.org/ --locationglobal 设置淘宝镜像源 npm config set registry https://registry.npm.taobao.org/ --locationglobal 需要更改淘宝镜像源地址…

物联网——TIM定时器、PWM驱动呼吸灯、舵机和直流电机

定时器概念&#xff08;常用于输出PWM波形&#xff0c;驱动电机&#xff09; 时间脉冲数时钟周期&#xff1b; 这里的脉冲数6553665536&#xff0c;支持定时器级联&#xff0c;从而延长定时 定时器类型 基本定时器原理图&#xff08;UI:更新中断&#xff0c; U:更新事件&#…

Jmeter的线程组之间传递参数

使用jemter做接口测试&#xff0c;有时候需要会遇到不同线程组之间调用相同变量的情况&#xff0c;最多见的就是token的传递&#xff0c;网上有很多处理方法&#xff0c;这里只记录setProperty的办法&#xff0c;一招鲜走遍天&#xff01; 首先我有两个线程组&#xff1a; 线程…

一种最大重叠离散小波包特征提取和支持向量机的ECG心电信号分类方法(MATLAB 2018)

目前小波分析算法常采用Mallat快速算法。该算法由与滤波器卷积、隔点采样和隔点插零等三个环节组成。由于实际使用的滤波器并不具有理想频域特性&#xff0c;使得在标准二进小波算法中存在着频率混叠和小波系数失真等缺点&#xff0c;在标准二进小波包算法中还存在频带错乱现象…

基于 Spring Boot 博客系统开发(十二)

基于 Spring Boot 博客系统开发&#xff08;十二&#xff09; 本系统是简易的个人博客系统开发&#xff0c;为了更加熟练地掌握 SprIng Boot 框架及相关技术的使用。&#x1f33f;&#x1f33f;&#x1f33f; 基于 Spring Boot 博客系统开发&#xff08;十一&#xff09;&…

热门新游 2024 植物大战僵尸杂交版 Mac 版本下载安装详细教程

最近植物大战僵尸杂交版可谓是非常的火&#xff0c;好多主播都在播这款游戏&#xff0c;我一个 Mac 党也想玩&#xff0c;可奈何该游戏目前只有 PC 版本&#xff0c;经过一番折腾终于在我的 Mac 上安装上了该游戏&#xff0c;分享给大家 其实安装过程也很简单&#xff0c;只需…

深度学习 --- stanford cs231 编程作业(如何在chrome中安装Google colab)

stanford cs231 编程作业(如何开始你的colab编程&#xff09; 斯坦福231n的所有作业都要求在colab里面做&#xff0c;colab可以为你提供免费的云计算。实际上在他的官网中也有关于如何安装colab的详细说明视频。 https://youtu.be/DsGd2e9JNH4https://youtu.be/DsGd2e9JNH4 我这…

GPU学习(1)

一、为什么要GPU 我们先看一个基本的神经网络计算 YF(x)AxB 这就是一次乘法一次加法 &#xff0c;也叫FMA&#xff0c;(fused multiply-add) 如果矩阵乘&#xff0c;就是上面的那个式子扩展一下&#xff0c;所以又用了这张老图 比如你要多执行好几个yAxB&#xff0c;可能比较简…

AI图书推荐:使用GitHub Copilot和ChatGPT辅助的Python编程

使用Python编写计算机程序变得更加简单了&#xff01;使用像GitHub Copilot和ChatGPT这样的AI辅助编码工具&#xff0c;将你的想法快速转化为应用程序。人工智能已经改变了我们编写计算机程序的方式。有了像Copilot和ChatGPT这样的工具&#xff0c;你可以用简单的英语描述你想要…

【docker】Docker的基本指令和HTML/PYTHON/C++的简单创建示例

目录 &#x1f30a;1. 什么是 Docker&#xff1f; &#x1f30a;2. Docker 安装 &#x1f30a;3. Docker基本指令 &#x1f30a;4. Docker 创建示例【联网情况】 &#x1f30d;4.1 示例&#xff1a;HTML &#x1f30d;4.2 示例&#xff1a;Python 脚本 &#x1f30d;4.3…

四信云-设备维保管理系统上线,实现设备全生命周期管理

在当今的制造业中&#xff0c;设备是企业生产的核心要素&#xff0c;是企业竞争力的基石。 随着企业发展规模不断扩大&#xff0c;设备数量急速增长&#xff0c;传统的手工管理方式已经无法满足企业需求&#xff0c;设备管理系统的出现则填补了市场需求空白&#xff0c;其目标…