本文使用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做服务端,附下载)的更多相关文章

  1. react native android 上传文件,Nodejs服务端获取上传的文件

    React Native端 使用react-native-image-picker 做出选择图片的操作,选择完成后,直接将图片Post至服务器,保存在服务器的某个地方(保存图片的路径需要公开显示),并 ...

  2. ASP.NET Core单文件和多文件上传并保存到服务端

    前言: 在我们日常开发中,关于图片,视频,音频,文档等相关文件上传并保存到服务端中是非常常见的一个功能,今天主要是把自己在开发中常用的两种方式记录下来方便一下直接使用,并且希望能够帮助到有需要的同学! ...

  3. linux下远程服务器批量执行命令及SFTP上传文件 -- python实现

    之前写过一个python远程执行命令的脚本,但在一个性能测试中,要将程序批量分发到不同服务器,程序无法使用,再将之前的脚本更新,加入批量上传的功能.之前脚本地址:http://www.cnblogs. ...

  4. SpringMVC上传文件以流方式判断类型附常用类型

    // 此类中判断类型所截取的byte 长度暂不确定,请使用者测试过使用 package com.tg.common.other; import com.tg.common.tginterface.TG ...

  5. C# 向服务器上传文件(客服端winform、服务端web)

    转载 首先写客服端,winform模拟一个post提交: /// <summary> /// 将本地文件上传到指定的服务器(HttpWebRequest方法) /// </summa ...

  6. 科普文:Node.js 如何上传文件到后端服务【转】

    原文链接 https://www.yuque.com/egg/nodejs/httpclient-upload 背景 互联网时代,无数服务是基于 HTTP 协议进行通信的. 除了常见的 前端浏览器 - ...

  7. 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件

    [源码下载] 重新想象 Windows 8.1 Store Apps (89) - 通信的新特性: 下载数据, 上传数据, 上传文件 作者:webabcd 介绍重新想象 Windows 8.1 Sto ...

  8. 前端AngularJS后端ASP.NET Web API上传文件

    本篇体验使用AngularJS向后端ASP.NET API控制器上传文件.    首先服务端: public class FilesController : ApiController { //usi ...

  9. python网络编程--FTP上传文件示例

    1.基础版(供学习了解原理使用,low) server服务端 import socket import struct import json server = socket.socket() ip_p ...

随机推荐

  1. 学习OpenCV研究报告指出系列(二)源代码被编译并配有实例project

    下载并安装CMake3.0.1       要自己编译OpenCV2.4.9的源代码.首先.必须下载编译工具,使用的比較多的编译工具是CMake. 以下摘录一段关于CMake的介绍: CMake是一个 ...

  2. 【bzoj2002】弹飞绵羊(分块)

    题目分析 题意:每个点都有一个值$v_i$,从一个点出发,每走到一个点,会跳到i+vi的位置,问需要跳多少次能跳出n?带修改. 此题可以用lct做,此处使用了分块:将序列分块后,每个点记录从此点最少跳 ...

  3. cordova 生成发行版apk,并添加证书 – 畅玩Coding

    原文:cordova 生成发行版apk,并添加证书 – 畅玩Coding 首先jdk生成证书. 1.进入jdk安装目录 D:\Java\jdk1.7.0\bin 2.执行命令 keytool -gen ...

  4. maven 依赖(依赖范围,聚合,继承等)

    目录: 1.什么是依赖? 2.依赖的管理:依赖的范围与传递,依赖的排除,依赖的原则(maven对依赖冲突的处理原则) 3.依赖的版本管理 4.继承与聚合 1.什么是依赖? 简单的讲,当jar包A需要j ...

  5. 【26.87%】【codeforces 712D】Memory and Scores

    time limit per test2 seconds memory limit per test512 megabytes inputstandard input outputstandard o ...

  6. BeforeFieldInit的小叙

    BeforeFieldInit是什么 上片的文章中我们看到了有静态构造函数,和没有静态构造函数,代码的执行顺序有着显著的区别.然后,我们反编译了下代码,发现了在类中有一个BeforeFieldInit ...

  7. Android 平台下Ftp 使用模拟器需要注意的问题

    以下代码在pc上测试通过,可是在android模拟器上就不工作,不过还可以链接到服务器但不能得到文件 纠结了半天,原来是模式的问题,具体请Google 模拟器中采用建议被动模式 public void ...

  8. 微信公众平台消息接口开发(31)微信浏览器HTTP_USER_AGENT判断

    微信公众平台开发 微信公众平台开发者 微信公众平台开发模式 微信浏览器 HTTP_USER_AGENT作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/archiv ...

  9. 接口测试——fiddler对soapui请求返回信息抓取

    原文:接口测试——fiddler对soapui请求返回信息抓取 背景:接口测试的时候,需要对接口的请求和返回信息进行查阅或者修改请求信息,可利用fiddler抓包工具对soapui的请求数据进行抓取或 ...

  10. WPF程序加入3D模型

    原文:WPF程序加入3D模型 版权声明:本文为博主原创文章,转载请附上链接地址. https://blog.csdn.net/ld15102891672/article/details/8006474 ...