You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Flutter真机无法与Flask服务器通信(CSV上传接口)的排查求助

问题:Flutter应用在Android真机上无法与Flask服务器的/predict/plot接口通信

背景信息

  • Flask服务器:运行于虚拟环境,提供/predict/plotPOST接口接收CSV文件,返回基于CSV数据生成的base64编码图片字符串。
  • Flutter应用:通过文件选择器选取CSV文件,上传至Flask接口,解码后展示返回的图片。

相关代码

Flutter代码(uploadCSV函数)

var dio = Dio();
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
  File file = File(result.files.single.path ?? " ");
  String fileName = file.path.split('/').last;
  String filePath = file.path;
  FormData data = FormData.fromMap(
      {'file': await MultipartFile.fromFile(filePath, filename: fileName)});
  try {
    var response = await dio.post("http://10.0.2.2:5000/predict/plot",
        data: data, onSendProgress: (int sent, int total) {
      print('$sent  $total');
    });
    _imagebase64 = jsonDecode(response.toString())['image'];
  } catch (e) {
    print(e.toString());
  }
} else {
  print("Response is null");
}

服务端代码(Flask app)

import joblib
import ast
from io import BytesIO
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import base64
from flask import Flask, request, jsonify

app = Flask(__name__)

plt.switch_backend('Agg')
@app.route('/predict/plot', methods=['POST'])
def plot():
    if 'file' not in request.files:
        obj = {"status": "fail", "message": 'No file part'}
        return jsonify(obj)

    file = request.files['file']

    # Validate file type
    if file.filename.endswith('.csv'):
        # Process CSV data
        df = pd.read_csv(file)
        # Create a simple plot
        data = df['Diseases']
        column_data = {}
        #plot
        for row in data:
                value = row[0]
                if value in column_data:
                    column_data[value] += 1
                else:
                    column_data[value] = 1

            # Generate a bar chart
        categories = list(column_data.keys())
        counts = list(column_data.values())

        plt.bar(categories, counts)
        plt.xlabel('Categories')
        plt.ylabel('Count')
        plt.title('Bar Chart')

        # Convert the plot to a base64-encoded image
        plot_image_base64 = plot_to_base64(plt)

        # Close the plot to release resources
        plt.close()

        # Return the base64-encoded image as part of the JSON response
        obj = {"status": "success", "location": df.loc[0, 'Location'], "image": plot_image_base64}
        print(obj)
        return jsonify(obj)
    else:
        obj = {"status": "fail", "message": 'Invalid file type. Please upload a CSV file'}
        return jsonify(obj)

def plot_to_base64(plt_obj):
    # Save the plot to a BytesIO object
    plot_bytes = BytesIO()
    plt_obj.savefig(plot_bytes, format='png')
    plot_bytes.seek(0)

    # Convert the plot to a base64-encoded image
    plot_base64 = base64.b64encode(plot_bytes.read()).decode('utf-8')
    return plot_base64

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

已尝试操作

将Flutter应用中的请求地址修改为PC的IP地址,但出现“connection timed out”和“socket exception”错误。

请求协助

  • 排查连接失败的根本原因
  • 验证网络连通性与防火墙设置
  • 配置必要的CORS
  • 完善Flutter应用的错误处理
  • 提供额外调试策略

可提供设备环境、完整错误日志等补充信息。

内容的提问来源于stack exchange,提问作者Saurav Haldar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.01 03:44:53