flask和socket结合使用实现客户端向服务端发送文件

1.实验效果

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
成功发送文件和接收文件


2.文件结构说明

在这里插入图片描述


3.操作步骤

(1)首先运行其服务端,处于监听状态;
(2)在运行客户端,之后根据https://127.0.0.1:5000/sendFiles进入浏览器,之后就可以操作发送文件了。


4.代码下载

https://github.com/KeepTryingTo/flask-socket.git


5.服务端文件

import os
import cv2
import json
import socket
import threading
#读取文件的最大数
max_len=1024

#端口号和IP地址
remote_PORT=5001
remote_IP='192.168.223.1'
remote_addr=(remote_IP,remote_PORT)

# 绑定IP地址和端口号PORT
socket_Server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
socket_Server.bind(remote_addr)

def Server_Recv_File(socket_Server):
    """
    :param socket: 服务端套接字
    :param root: 主窗口
    :return:
    """

    while True:
        # 监听
        socket_Server.listen()
        print('正在监听来自客户端的消息......')

        socket, addr = socket_Server.accept()

        #获取客户端发送的消息头
        msg_header=socket.recv(max_len)
        if msg_header=='Gameover':
            socket.close()
            break
        header=json.loads(msg_header.decode('utf-8'))
        #输出客户端发送的消息头信息
        print(header)
        #保存接收文件的地方
        curr_path=os.getcwd()
        filename=curr_path+'\\recvFiles\\'+header['filename']+header['msg_type']

        get_file_Size=header['msg_len']
        file_size=0
        #输出文件名和文件大小
        print('文件名: {}'.format(filename))
        print('file_size: {}'.format(get_file_Size))
        recv_count=0
        #如果文件不存在则创建
        if os.path.exists(filename)==False:
            with open(filename,'wb') as fp:
                while file_size!=get_file_Size:
                    message=socket.recv(max_len)
                    fp.write(message)
                    file_size+=len(message)
                    print(file_size)
                    recv_count+=1
        else:
            with open(filename, 'wb') as fp:
                while file_size != get_file_Size:
                    message = socket.recv(max_len)
                    fp.write(message)
                    file_size += len(message)
                    print(file_size)
                    recv_count+=1
        print('接收次数: {}'.format(recv_count))
        print('接收完成...')

if __name__=='__main__':
    print('Pycharm')
    disconnection=False
    Server_Recv_File(socket_Server)


6.客户端文件

import os
import json
import socket
from flask_wtf import FlaskForm
from flask_wtf.file import FileField
from flask_sqlalchemy import SQLAlchemy
from werkzeug.utils import secure_filename
from sqlalchemy import String,Column,Integer
from wtforms.validators import DataRequired,Length
from flask import request,redirect,url_for,Flask,render_template,flash
from wtforms import StringField,TelField,DateField,SubmitField,PasswordField

#定义读取的最大文件数
max_len=1024


app=Flask(__name__)
app.secret_key='files'

class Config:
    SQLALCHEMY_DATABASE_URI='mysql+pymysql://root:root@127.0.0.1:3306/main'
    SQLALCHEMY_TRACK_MODIFICATIONS=False

app.config.from_object(Config)
mysql=SQLAlchemy(app)

class FormFiles(FlaskForm):
    filename=FileField(label='传输文件',validators=[DataRequired()])
    submit=SubmitField(label='提交文件')

# class FormText(FlaskForm):
#     endtext=StringField(label='结束符')
#     end = SubmitField(label='结束传输')

# http://127.0.0.1:5000/sendFiles
@app.route('/sendFiles',methods=['POST','GET'])
def sendFiles():
    formfiles=FormFiles()
    if request.method=='POST':
        if formfiles.validate_on_submit():
            # 定义端口和IP地址
            remote_PORT = 5001
            remote_IP = '192.168.223.1'
            remote_addr = (remote_IP, remote_PORT)
            # 绑定端口号和IP地址
            Socket_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            Socket_socket.connect(remote_addr)

            if formfiles.filename.data!=None:
                filename=secure_filename(formfiles.filename.data.filename)
                name=filename
                formfiles.filename.data.save('files/'+filename)
                #切分文件名和点后缀名
                filename = 'files/' + filename
                file,type_file=os.path.splitext(name)
                #获取文件大小
                file_Size=os.stat(filename).st_size
                #定义发送消息头
                msg_header={'filename':file,'msg_type':type_file,'msg_len':file_Size}
                msg_header_bytes=bytes(json.dumps(msg_header),encoding='utf-8')
                #当消息头的长度不满1024时,使用空格填充
                msg_header_bytes+=b''*(max_len-len(msg_header_bytes))
                #发送消息头
                Socket_socket.send(msg_header_bytes)
                file_len=0
                recv_count=0
                #发送的文件消息头大小
                print('msg_header_bytes: {}'.format(len(msg_header_bytes)))
                # 发送的文件大小
                print('file_size: {}'.format(file_Size))
                #发送文件的类型
                print('type_file: {}'.format(type_file))

                with open(filename,'rb') as fp:
                    while file_len!=file_Size:
                        message=fp.read(max_len)
                        Socket_socket.send(message)
                        file_len+=len(message)
                        recv_count+=1
                flash(message='文件传输成功!')
                print('发送次数: {}'.format(recv_count))
                print('发送完毕!')
            else:
                # 发送结束消息
                print('结束文件传输')
                flash(message='文件传输结束!')
                endstr='Gameover'.encode('utf-8')
                Socket_socket.send(endstr)
                Socket_socket.close()

    return render_template('index.html',formfiles=formfiles)


@app.route('/index',methods=['POST','GET'])
def index():
    formfiles=FormFiles()
    return render_template('index.html',formfiles=formfiles)


if __name__ == '__main__':
    print('Pycharm')
    app.run(debug=True)

# import os
# from torchstat import stat
# import torchvision.models as models
#
# model=models.shufflenet_v2_x1_0()
# stat(model,(3,224,224))


7.前端文件

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <style>
        body {
            position:relative;
        }
        .convery {
            position:relative;
            margin:auto;
            width:200px;
            height:200px;
            border:2px solid #000000;
            margin-top:100px;
        }
        .file {
            position:absolute;
            width:30px;
            height:20px;
            margin-top:30px;
            margin-left:50px;
        }
        .submit {
            position:absolute;
            width:35px;
            height:25px;
            margin-left:50px;
            margin-top:70px;
        }
         .end {
            position:absolute;
            width:200px;
            height:90px;
            margin-left:900px;
            margin-top:-25px;
        }
        h3 {
            margin-top:20px;
            margin-left:50px;
        }
        .flash {
            color:red;
            font-size:30px;
            margin:auto;
            margin-left:650px;
        }
    </style>
</head>
<body>
    <div class="flash">
         {% with messages=get_flashed_messages()%}
            {% if messages %}
                {% for message in messages %}
                    <div><p style="color:red">{{message}}</p></div>
                {% endfor %}
            {% endif%}
        {% endwith %}
    </div>
    <form class="convery" action="http://127.0.0.1:5000/sendFiles" method="POST" enctype="multipart/form-data">
        {{formfiles.csrf_token()}}

        <h3>文件传输</h3>
        <label class="file">
            {{formfiles.filename}}
        </label>
        <label class="submit">
            {{formfiles.submit}}
        </label>
<!--        <label class="end">-->
<!--            {{formfiles.end}}-->
<!--        </label>-->
<!--        <button name="结束" value="Gameover"></button>-->
    </form >

</body>
</html>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值