Qt通过HTTP POST上传文件(python做服务端,附下载)
本文使用Qt Creator用HTTP POST的方法上传文件,并给出一个上传文件的例程。
本文主要客户端,所以对于服务器端程序编写的描述会比较简略
服务器使用Django编写,django服务器接收文件的方法在文章http://www.cnblogs.com/fnng/p/3740274.html中有较为清晰的讲解,我搭建的服务器端程序除了没有网页客户端以及部分变量名称不同以外,基本上与这篇文章的服务器搭建过程一样。
如果服务器端程序发生变化,这篇文章后面给出的客户端例程可能就不再适用。因此如果运行客户端程序之后发现服务器端不能接收到文件,不要直接认为这篇文章给出的客户端例程是错误的,也可能是其他问题导致的。
在制作程序时,我并没有尝试上传大文件、同时上传多个文件以及文件名中包含中文这三种情况。因此在这三种情况下程序很有可能出现BUG。
示例程序链接:http://pan.baidu.com/s/1i5NWsHR
1. 服务器端
服务器端程序基本参照http://www.cnblogs.com/fnng/p/3740274.html。这里直接贴出代码,搭建过程以及代码描述等就不进行说明了。
disk/views.py:
from django.shortcuts import render,render_to_response
from django.http import HttpResponse
from django import forms
from .models import User
import os
# Create your views here.
class UserForm(forms.Form):
username=forms.CharField()
upload_file=forms.FileField()
def index(request):
if request.method=="POST":
uf=UserForm(request.POST,request.FILES)
print(str(request.POST))
print(str(request.FILES))
if uf.is_valid():
username=uf.cleaned_data['username']
upload_file=uf.cleaned_data['upload_file']
dir_name='./upload/'+username
if os.path.exists(dir_name)==False:
os.mkdir(dir_name)
user=User()
user.username=username
user.upload_file=upload_file
user.save()
return HttpResponse('upload ok!')
else:
uf=UserForm()
return HttpResponse('000!')
disk/models.py:
from django.db import models
# Create your models here.
def content_file_name(instance,filename):
s='/'.join(['upload',instance.username,filename])
return s
class User(models.Model):
username=models.CharField(max_length=30)
upload_file=models.FileField(upload_to=content_file_name)
def __unicode__(self):
return self.username
disk/urls.py:
from django.conf.urls import url
from . import views
urlpatterns=[
#View the information of user.
url(r'^$',views.index,name='index'),
]
2. 客户端程序应该上传的数据
客户端程序在向服务器端上传文件时,不能只上传文件的内容。如果上传的数据中只有文件的内容,那么服务器端是不能正常接收到文件的。客户端上传的内容应该包括普通的表单数据、文件头部以及文件内容三大部分,并对需要传输的数据进行规范化地拼接,按照特定的格式上传数据。
对于我用django制作的这个服务器端程序来说,客户端需要上传一个name为username的普通数据,以及一个name为upload_file的文件数据。下面的代码将需要发送的数据进行拼接并使用POST请求将数据发送给服务器。
3. 新建工程过程中需要注意的地方
在pro文件中要加上QT += network 如果不添加会报错
在代码文件的最前面添加包含 #include 。(不添加的话程序会编译失败)我自己在学习使用Qt进行HTTP通信时发现网上的很多文章在贴出代码时并没有贴出前面的#include部分,导致我花了很长时间去找需要引用的文件。
4. 客户端上传文件的代码
void UpLoadForm(QString Path,QMap<</span>QString,QString> params,QStringfileFormName,QFile *uploadFile,QString newFileName){
QString BOUNDARY=QUuid::createUuid().toString();
QByteArray sb=QByteArray();
//先上传普通的表单数据
for(QMap<</span>QString,QString>::Iteratort=params.begin();t!=params.end();t++){
sb.append("--"+BOUNDARY+"\r\n");
sb.append(QString("Content-Disposition: form-data;name=\"")+t.key()+QString("\"")+QString("\r\n"));
sb.append("\r\n");
sb.append(t.value()+"\r\n");
}
//上传文件的头部
sb.append("--"+BOUNDARY+"\r\n");
sb.append(QString("Content-Disposition: form-data;name=\"")+fileFormName+QString("\";filename=\"")+newFileName+QString("\"")+QString("\r\n"));
sb.append("\r\n");
//上传文件内容
if(!uploadFile->open(QIODevice::ReadOnly)){
return;
}
sb.append(uploadFile->readAll());
sb.append("\r\n");
sb.append("--"+BOUNDARY+"\r\n");
//编辑HTTP头部
QNetworkAccessManager *_uploadManager=new QNetworkAccessManager();
QNetworkRequest request=QNetworkRequest(QUrl(Path));
request.setRawHeader(QString("Content-Type").toLatin1(),QString("multipart/form-data;boundary="+BOUNDARY).toLatin1());
request.setRawHeader(QString("Content-Length").toLatin1(),QString::number(sb.length()).toLatin1());
//执行post请求
_uploadManager->post(request,sb);
}
5. 编写main函数调用前面上传文件的代码,完成测试。
在这里,我们提交了一个name为username的普通表单数据,它的值为10005。我们同时还提交了一个name为upload_file的文件数据。我们上传了本地的”:/Untitled.png”文件,上传成功之后服务器会接收到这个文件,保存时命名为”1A.png”
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString path="http://192.168.252.2:8000/disk/"; //服务器的url
QMap<</span>QString,QString> params_send; //上传的普通参数 在本程序中 需要上传一个普通参数为"username"
params_send.insert("username","10005");
QString fileFormName="upload_file"; //上传文件表单中的名字
QFile *file=new QFile(":/Untitled.png");
QString newFileName="1A.png";
UpLoadForm(path,params_send,fileFormName,file,newFileName);
return a.exec();
}
6. 效果
我们把这张图片”untitled.png”上传给服务器
服务器接收到了客户端发来的图片,表单数据中username=10005,所以新建了一个文件夹”10005”,将接收到的图片保存在了这个文件夹中并命名为”1A.png”
7. 参考资料
http://www.cnblogs.com/fnng/p/3740274.html
https://forum.qt.io/topic/11086/solved-qnetworkaccessmanager-uploading-files
http://blog.csdn.net/lmj623565791/article/details/23781773
如果发现问题欢迎在下面留言或私信我
http://blog.sina.com.cn/s/blog_15d207b300102xvqz.html
Qt通过HTTP POST上传文件(python做服务端,附下载)的更多相关文章
- react native android 上传文件,Nodejs服务端获取上传的文件
React Native端 使用react-native-image-picker 做出选择图片的操作,选择完成后,直接将图片Post至服务器,保存在服务器的某个地方(保存图片的路径需要公开显示),并 ...
- ASP.NET Core单文件和多文件上传并保存到服务端
前言: 在我们日常开发中,关于图片,视频,音频,文档等相关文件上传并保存到服务端中是非常常见的一个功能,今天主要是把自己在开发中常用的两种方式记录下来方便一下直接使用,并且希望能够帮助到有需要的同学! ...
- linux下远程服务器批量执行命令及SFTP上传文件 -- python实现
之前写过一个python远程执行命令的脚本,但在一个性能测试中,要将程序批量分发到不同服务器,程序无法使用,再将之前的脚本更新,加入批量上传的功能.之前脚本地址:http://www.cnblogs. ...
- SpringMVC上传文件以流方式判断类型附常用类型
// 此类中判断类型所截取的byte 长度暂不确定,请使用者测试过使用 package com.tg.common.other; import com.tg.common.tginterface.TG ...
- C# 向服务器上传文件(客服端winform、服务端web)
转载 首先写客服端,winform模拟一个post提交: /// <summary> /// 将本地文件上传到指定的服务器(HttpWebRequest方法) /// </summa ...
- 科普文:Node.js 如何上传文件到后端服务【转】
原文链接 https://www.yuque.com/egg/nodejs/httpclient-upload 背景 互联网时代,无数服务是基于 HTTP 协议进行通信的. 除了常见的 前端浏览器 - ...
- 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件
[源码下载] 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件 作者:webabcd 介绍重新想象 Windows 8.1 Sto ...
- 前端AngularJS后端ASP.NET Web API上传文件
本篇体验使用AngularJS向后端ASP.NET API控制器上传文件. 首先服务端: public class FilesController : ApiController { //usi ...
- python网络编程--FTP上传文件示例
1.基础版(供学习了解原理使用,low) server服务端 import socket import struct import json server = socket.socket() ip_p ...
随机推荐
- Shell脚本实现在Linux系统中自动安装JDK
A:本脚本运行的机器,Linux B:待安装JDK的机器, Linux 首先在脚本运行的机器A上确定可以ssh无密码登录到待安装jdk的机器B上,然后就可以在A上运行本脚本: 复制代码 代码如下: $ ...
- SQL生成n位随机字符串
--1.随着newid() go --创建一个视图(因为不能在功能直接用于newid()) create view vnewid as select newid() N'MacoId'; go --创 ...
- hadoop中国字、词频统计和排序
例如需求,下面: 有被看作图输入文件中. 代表ip地址,之后的偶数列代表搜索词.数字(奇数列)代表搜索次数.使用"\t"分隔.如今须要对搜索词进行分词并统计词频,此处不考虑搜索次数 ...
- Linux四个常用的指挥机关处理具体的解释
原版的Blog.转载请注明出处 http://blog.csdn.net/hello_hwc?viewmode=contents 权限 对于文件 r 可读 w 可写 x 可运行 对于文件夹 r 能够列 ...
- JTextpane 加入的行号
最近项目需求,在需求JTextPane加入行号等信息,网上找了半天才发现JTextArea加入行号信息.copy正在研究在线程序.他发现自己能够做出改变来改变JTextPane显示行号. 代码: pa ...
- mongose TypeError: Cannot read property 'findOne' of undefined
最近在node的一个项目中,需要在model的一个数据表中写一个钩子函数去调用另外一个文件中的方法,一开始我采用了将此方法放入到global中,直接从global.meteod这样去获取.后来我又尝试 ...
- C# 调用PowerShell方法
PowerShell应为编写和运行都很方便,所以为了重复利用,经常写了一些小方法或者PS代码片段.使用的时候可能会很难找到自己想要的那个方法,如果要是有一个界面把这些代码管理起来并且调用,那就很爽了 ...
- March 29th, 2015, Thread Name is odd by increasing 1
public class Fabric extends Thread{ public static void main(String args[]){ Thread t = new Thread(ne ...
- NYOJ 24 素数的距离问题
素数的距离问题 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描写叙述 如今给出你一些数.要求你写出一个程序,输出这些整数相邻近期的素数,并输出其相距长度.假设左右有等距离长 ...
- STL algorithm算法lexicographical_compare(30)
lexicographical_compare原型: std::lexicographical_compare default (1) template <class InputIterator ...