• Flask初体验


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

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

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

    1.python: reverse_ssh_server.sh

    1. import socket
    2. import threading
    3. from flask import Flask, render_template, jsonify, request
    4. import requests
    5. from sys import argv
    6. import multiprocessing
    7. TCP_PORT = 8888
    8. WEB_PORT = 5000
    9. CLIENT_MAX_LEN = 15
    10. app= Flask(__name__, template_folder="./web") #, static_folder="./web"
    11. connected_devices = []
    12. # TCP服务器
    13. def tcp_server():
    14. host = '0.0.0.0'
    15. port = TCP_PORT
    16. server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    17. try:
    18. server_socket.bind((host, port))
    19. server_socket.listen(15)
    20. except Exception as e:
    21. print(f"app port {port} bind error", e)
    22. return;
    23. print(f"TCP服务器已启动,监听端口 {port}...")
    24. while True:
    25. try:
    26. if(app is None):
    27. continue;
    28. client_socket, addr = server_socket.accept()
    29. #print(f"连接来自 {addr}")
    30. if(len(connected_devices)>CLIENT_MAX_LEN):
    31. client_socket.close()
    32. continue
    33. json = {}
    34. json["dev"] = f"{addr}"
    35. dev_login(json)
    36. print(connected_devices)
    37. except Exception as e:
    38. print("client accept error.", e);
    39. server_socket.close();
    40. return;
    41. def dev_login(dev_addr):
    42. url = f'http://localhost:{WEB_PORT}/api/devices/dev_login'
    43. headers = {'Content-Type': 'application/json'}
    44. response = requests.post(url, json=dev_addr, headers=headers)
    45. print("dev_login", response.json()) # 打印服务器返回的 JSON 响应
    46. # Web页面
    47. @app.route('/')
    48. def index():
    49. connected_devices = app.config['connected_devices']
    50. return render_template('index.html', devices=connected_devices)
    51. @app.route('/api/devices')
    52. def get_device_list():
    53. connected_devices = app.config['connected_devices']
    54. # 这里应该是获取设备列表的逻辑,暂时用一个简单的列表代替
    55. # Assuming connected_devices is a multiprocessing.Queue
    56. ret = jsonify(connected_devices)
    57. print(ret)
    58. return ret
    59. @app.route('/api/devices/dev_login', methods=['POST'])
    60. def handle_post():
    61. # 获取 POST 请求中的 JSON 数据
    62. json_data = request.json["dev"]
    63. connected_devices = app.config['connected_devices']
    64. connected_devices.append(json_data);
    65. app.config['connected_devices'] = connected_devices
    66. # 在这里处理 JSON 数据,这里只是简单地返回接收到的 JSON 数据
    67. print("on_handle_post:", json_data, connected_devices)
    68. return jsonify(json_data)
    69. if __name__ == '__main__':
    70. if len(argv)>=2:
    71. WEB_PORT = int(argv[1])
    72. if len(argv)>=3:
    73. TCP_PORT = int(argv[2])
    74. print(f"web port:{WEB_PORT}, tcp port:{TCP_PORT}")
    75. # 启动TCP服务器和Web应用
    76. app.config['connected_devices'] = connected_devices
    77. tcp_thread = threading.Thread(target=tcp_server)
    78. tcp_thread.start()
    79. app.run(debug=True, port=WEB_PORT)

    2.web Flask使用的index.html

    1. html>
    2. <html>
    3. <head>
    4. <title>Device Listtitle>
    5. head>
    6. <body>
    7. <h1>Device Listh1>
    8. <ul id="device-list">
    9. <li>ip:portli>
    10. ul>
    11. <script>
    12. function updateDeviceList() {
    13. // 发送 AJAX 请求获取设备列表
    14. var xhr = new XMLHttpRequest();
    15. xhr.onreadystatechange = function() {
    16. if (xhr.readyState == XMLHttpRequest.DONE) {
    17. if (xhr.status == 200) {
    18. // 解析 JSON 响应
    19. var devices = JSzeON.parse(xhr.responseText);
    20. // 清空设备列表
    21. document.getElementById("device-list").innerHTML = "";
    22. // 遍历设备列表并添加到页面中
    23. devices.forEach(function(device) {
    24. var li = document.createElement("li");
    25. li.textContent = device; //device.name
    26. document.getElementById("device-list").appendChild(li);
    27. });
    28. }
    29. }
    30. };
    31. xhr.open("GET", "/api/devices", true);
    32. xhr.send();
    33. }
    34. // 页面加载时立即执行一次更新
    35. updateDeviceList();
    36. // 定时刷新,1秒执行一次
    37. setInterval(updateDeviceList, 1000);
    38. script>
    39. body>
    40. 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

    1. #!/usr/bin/env python3
    2. # -*- coding: utf-8 -*-
    3. # 获取当前脚本文件所在目录的父目录,并构建相对路径
    4. import os
    5. import sys
    6. current_dir = os.path.dirname(os.path.abspath(__file__))
    7. project_path = os.path.join(current_dir, '..')
    8. sys.path.append(project_path)
    9. sys.path.append(current_dir)
    10. import gpLog
    11. import paho.mqtt.client as mqtt
    12. from datetime import datetime
    13. import cv2
    14. import requests
    15. import numpy as np
    16. def gpWebPost_PostImage(url:str, cv2Image, ai_class:int):
    17. if not url.startswith("http://"):
    18. # 设置 POST 请求的 URL
    19. url = f'http://{url}'
    20. # 设置要发送的文件
    21. files = {
    22. 'ai_snapshot': cv2Image # 将文件打开为二进制模式
    23. }
    24. data = {
    25. 'ai_class': 1,
    26. }
    27. jsonArg ={}
    28. jsonArg["ai_class"]=ai_class
    29. # 发送 POST 请求
    30. response = requests.post(url, files=files, json=jsonArg, data=data)
    31. # 检查响应
    32. if response.status_code == 200:
    33. return True
    34. else:
    35. return False
    36. def gpWebPost_TestPostImage():
    37. # 读取图像
    38. url = "http://192.168.0.1:8080/aiimage/dev_0001/ch01"
    39. image = cv2.imread(r'/home/lubancat/图片/Rumelhart_rect.jpg')
    40. # 将图像转换为字节流
    41. _, img_encoded = cv2.imencode('.jpg', image)
    42. image_data = img_encoded.tobytes()
    43. gpWebPost_PostImage(url, image_data, 1)

  • 相关阅读:
    3-docker安装centos7
    Qt 关于窗口全屏显示与退出全屏的实现
    ubuntu系统使用bing wallpaper壁纸
    SQL Prompt10 安装激活教程,让你写sql 如鱼得水
    static学习
    如何读取resources目录下的文件路径(九种方式)
    【云原生】docker环境中安装mysql、redis服务
    旋转框目标检测mmrotate v0.3.1 训练DOTA数据集(二)
    idea无法添加spring MVC框架支持
    Ubuntu服务器的GitLab部署
  • 原文地址:https://blog.csdn.net/twicave/article/details/139289101