C++ Post上传文件到Django

C++ Post上传文件到Django

Django Api:

def uploadfile(request):
    if request.method == "POST":  # 请求方法为POST时,进行处理
        myFile = request.FILES.get("myfile", None)  # 获取上传的文件,如果没有文件,则默认为None
        if not myFile:
            return HttpResponse("no files for upload!")
        destination = open(os.path.join("F:\\upload", myFile.name), 'wb+')  # 打开特定的文件进行二进制的写操作
        for chunk in myFile.chunks():  # 分块写入文件
            destination.write(chunk)
        destination.close()
        return HttpResponse("upload over!")

注意要在对应web项目下的urls.py里把这个方法发布出去(网址),访问这个网址使用api

如果要请求结束后发送一个json的返回值可以这么写

return HttpResponse(json.dumps(request, ensure_ascii = False))

这里的result是一个json格式的字典,比如:

result = {
	fileName:name
	code : 0
}

c++创建Http Post请求发送文件

参考资料
参考资料
参考资料
头文件

#pragma once
#include <iostream>
using namespace std;

typedef size_t(*pfn_write_data)(char *buffer, size_t size, size_t nitems, void *pattach);
//优点:不需要依赖第三方库,缺点:功能单一如:不支持301跳转
class CHttpConnect
{
public:
    CHttpConnect();
    ~CHttpConnect(void);
    static string HttpPost(std::string host, std::string post);
    static string HttpPostFile(std::string host, std::string post, std::string filename);
    static string HttpGet(std::string host);
    static string GetFileContext(std::string filename);
    static void HttpDownload(std::string host, pfn_write_data pwrite_data, void* pattach = NULL);
private:
    static short ParseUrl(std::string& host, std::string& path);
    static string SocketHttp(std::string host, std::string request, short port, pfn_write_data pwrite_data = NULL, void* pattach = NULL);
    static string SocketHttp1(std::string host, std::string request, short port, pfn_write_data pwrite_data = NULL, void* pattach = NULL);
};

cpp文件


#include "CHttpConnect.h"
#include <WinSock.h>
#include <stdio.h>
#include <sstream>
#include <iostream>
#include <algorithm>
#ifdef WIN32
#pragma comment(lib,"ws2_32.lib")
#endif
CHttpConnect::CHttpConnect()
{
}
CHttpConnect::~CHttpConnect(void)
{
}
short CHttpConnect::ParseUrl(std::string& host, std::string& path)
{
    short nPort = 80;
    //处理主机域名不能带http开头
    int pos = host.find("http://");
    if (pos >= 0)
    {
        int endPos = host.find("/", pos + 7);
        if (endPos >= 0)
        {
            path = host.substr(endPos, host.length() - endPos);
            host = host.substr(pos + 7, endPos - pos - 7);
        }
        else
        {
            host = host.substr(pos + 7, host.length() - pos - 7);
        }
        pos = host.find(":");
        if (pos >= 0)
        {
            string sPort = host.substr(pos + 1, host.length() - pos - 1);
            nPort = atoi(sPort.c_str());
            host = host.substr(0, pos);
        }
    }
    else
    {
        int endPos = host.find("/");
        if (endPos >= 0)
        {
            path = host.substr(endPos, host.length() - endPos);
            host = host.substr(0, endPos);
        }
        pos = host.find(":");
        if (pos >= 0)
        {
            string sPort = host.substr(pos + 1, host.length() - pos - 1);
            nPort = atoi(sPort.c_str());
            host = host.substr(0, pos);
        }
    }
    return nPort;
}
std::string CHttpConnect::SocketHttp(std::string host, std::string request, short port, pfn_write_data pwrite_data, void* pattach)
{
#ifdef WIN32
    //此处一定要初始化一下,否则gethostbyname返回一直为空
    WSADATA wsa = { 0 };
    WSAStartup(MAKEWORD(2, 2), &wsa);
#endif
    int sockfd;
    struct sockaddr_in address;
    struct hostent *server;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    address.sin_family = AF_INET;
    address.sin_port = htons(port);
    server = gethostbyname(host.c_str());
    memcpy((char *)&address.sin_addr.s_addr, (char*)server->h_addr, server->h_length);
    if (-1 == connect(sockfd, (struct sockaddr *)&address, sizeof(address))) {
        //ASSERT("连接失败");
        return "连接失败";
    }
#ifdef WIN32
    send(sockfd, request.c_str(), request.size(), 0);
#else
    write(sockfd, request.c_str(), request.size());
#endif
    char buf[1024];
    int actual = -1;
    bool checkHttpHead = true;
    LPCSTR lpLine = NULL;
    std::stringstream out;
#ifdef WIN32
    while (actual = recv(sockfd, buf, 1024, 0))
#else
    while (actual = read(sockfd, buf, 1024))
#endif
    {
        if (checkHttpHead)
        {
            if ((lpLine = strstr(buf, "\r\n\r\n")))
            {
                int offset = lpLine - buf + strlen("\r\n\r\n");//出现的指针减去起始指针得到长度
                if (pwrite_data == NULL) {
                    out << string(buf + offset, actual - offset) << endl;//数据写到缓存
                    string str_result = out.str();
                    //cout << str_result << endl;
                }
                else
                    pwrite_data(buf + offset, 1, actual - offset, pattach);
                checkHttpHead = false;//http头读取完毕
                lpLine = NULL;//指针放空
            }
            continue;
        }
        if (pwrite_data == NULL) {
            out << string(buf, actual) << endl;//数据写到缓存
        }
        else {
            pwrite_data(buf, 1, actual, pattach);
        }
    }
#ifdef WIN32
    closesocket(sockfd);
    //此处一定要初始化一下,否则gethostbyname返回一直为空
    ::WSACleanup();
#else
    close(sockfd);
#endif
    string str_result = out.str();
    return str_result;
}
std::string CHttpConnect::SocketHttp1(std::string host, std::string request, short port, pfn_write_data pwrite_data, void* pattach)
{
#ifdef WIN32
    //此处一定要初始化一下,否则gethostbyname返回一直为空
    WSADATA wsa = { 0 };
    WSAStartup(MAKEWORD(2, 2), &wsa);
#endif
    int sockfd;
    struct sockaddr_in address;
    struct hostent *server;
    sockfd = socket(AF_INET, SOCK_STREAM, 0);
    address.sin_family = AF_INET;
    address.sin_port = htons(port);
    server = gethostbyname(host.c_str());
    memcpy((char *)&address.sin_addr.s_addr, (char*)server->h_addr, server->h_length);
    if (-1 == connect(sockfd, (struct sockaddr *)&address, sizeof(address))) {
        return "连接失败";
    }
#ifdef WIN32
    send(sockfd, request.c_str(), request.size(), 0);
#else
    write(sockfd, request.c_str(), request.size());
#endif
    char buf[1024];
    int actual = -1;
    bool checkHttpHead = true;
    LPCSTR lpLine = NULL;
    std::stringstream out;
#ifdef WIN32
    while (actual = recv(sockfd, buf, 1024, 0))
#else
    while (actual = read(sockfd, buf, 1024))
#endif
    {
        if (checkHttpHead)
        {
            if ((lpLine = strstr(buf, "\r\n\r\n")))
            {
                int offset = lpLine - buf + strlen("\r\n\r\n");//出现的指针减去起始指针得到长度
                if (pwrite_data == NULL) {
                    out << string(buf + offset, actual - offset) << endl;//数据写到缓存
                    string str_result = out.str();
                    //cout << str_result << endl;
                }
                else {
                    pwrite_data(buf + offset, 1, actual - offset, pattach);
                }
                checkHttpHead = false;//http头读取完毕
                lpLine = NULL;//指针放空
            }
            continue;
        }
        if (pwrite_data == NULL) {
            out << string(buf, actual) << endl;//数据写到缓存
#ifdef WIN32
            closesocket(sockfd);
            //此处一定要初始化一下,否则gethostbyname返回一直为空
            ::WSACleanup();
#else
            close(sockfd);
#endif
            string str_result = out.str();
            return str_result;
        }
    }
#ifdef WIN32
    closesocket(sockfd);
    //此处一定要初始化一下,否则gethostbyname返回一直为空
    ::WSACleanup();
#else
    close(sockfd);
#endif
    string str_result = out.str();
    return str_result;
}
// 文件的二进制数据在body里面
std::string CHttpConnect::HttpPost(std::string host, std::string post)
{
    string path;
    short nPort = ParseUrl(host, path);
    //POST请求方式
    std::stringstream stream;
    stream << "POST " << path;
    stream << " HTTP/1.0\r\n";
    stream << "Host: " << host << "\r\n";
    stream << "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n";
    stream << "Content-Type:application/x-www-form-urlencoded\r\n";
    stream << "Content-Length:" << post.length() << "\r\n";
    stream << "Connection:close\r\n\r\n";
    stream << post;
    return SocketHttp(host, stream.str(), nPort);
}

std::string CHttpConnect::HttpGet(std::string host)
{
    //GET请求方式
    std::stringstream stream;
    string path;
    short nPort = ParseUrl(host, path);
    stream << "GET " << path;
    stream << " HTTP/1.0\r\n";
    stream << "Host: " << host << "\r\n";
    stream << "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n";
    stream << "Connection:close\r\n\r\n";
    return SocketHttp(host, stream.str(), nPort);
}
void CHttpConnect::HttpDownload(std::string host, pfn_write_data pwrite_data, void* pattach)
{
    //GET请求方式
    std::stringstream stream;
    string path;
    short nPort = ParseUrl(host, path);
    stream << "GET " << path;
    stream << " HTTP/1.0\r\n";
    stream << "Host: " << host << "\r\n";
    stream << "User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; zh-CN; rv:1.9.2.3) Gecko/20100401 Firefox/3.6.3\r\n";
    stream << "Connection:close\r\n\r\n";
    SocketHttp(host, stream.str(), nPort, pwrite_data, pattach);
}

// 文件的数据在FILES里,但是这个方式好像有点问题,发送结束后程序不结束
string CHttpConnect::HttpPostFile(std::string host, std::string post, string filename)
{
    string path;
    short nPort = ParseUrl(host, path);
    //POST请求方式
    std::string header("");

    header += "POST ";
    header += path;
    header += " HTTP/1.1\r\n";
    header += "User-Agent: Mozilla/4.0\r\n";
    header += "Host: ";
    header += host;
    header += "\r\n";
    header += "Pragma: no-cache\r\n";
    header += "Accept: */*\r\n";
    header += "Content-Type: multipart/form-data; boundary=----------------------------64b23e4066ed\r\n";
    std::string content("");
    content += "------------------------------64b23e4066ed\r\n";
    content += "Content-Disposition: form-data; name='id'\r\n\r\n";
    content += "3365863\r\n";
    content += "------------------------------64b23e4066ed\r\n";
    content += "Content-Disposition: form-data; name=myfile; filename=";
    content += filename;
    content += "\r\n";
    content += "Content-Type: custom\r\n\r\n";
    content += post;
    content += "\r\n------------------------------64b23e4066ed--\r\n";

    char temp[64] = { 0 };
    sprintf(temp, "Content-Length: %d\r\n\r\n", content.length());
    header += temp;
    std::string str_http_request = header + content;
    return SocketHttp1(host, str_http_request, nPort);
}

string CHttpConnect::GetFileContext(string filename)
{
    const char *name = filename.c_str();
    FILE *fp = std::fopen(name, "rb");
    if (fp) {
        string contexts;
        fseek(fp, 0, SEEK_END);
        contexts.resize(ftell(fp));
        rewind(fp);
        fread(&contexts[0], 1, contexts.size(), fp);
        fclose(fp);
        return contexts;
    }
    throw(errno);
}
int main(int argc, char* argv[])
{
    string path = "C:\\Users\\hp\\Desktop\\cailiao\\4.jpg";

    string post = CHttpConnect::GetFileContext(path);
    string result = CHttpConnect::HttpPostFile("127.0.0.1:8111/blog/uploadfile", post,"4.jpg");
    //string result = CHttpConnect::HttpPost("127.0.0.1:8111/blog/uploadfile", post);
    std::cout << result << std::endl;
    return 0;
}

结束

附加

Qt 发送Post

发送Json

QNetworkAccessManager *manage = QNetworkAccessManager ();
QNetRequest request;
request.setUrl(QUrl(…));
QHttpMultipart * multipart = new QHttpMultipart (QHttpMultipart::FormDataType);
QHttpPart metapart;
metapart.setHeader(QNetworkRequest::ContextTypeHeader,“application/json”);
metaport.setHeader(QNetworkRequest::ContextTypeHeader,QVariant(“form-data;name=“tool_name””));
metaport.setBody(“seagullxxx”);
multipart.append(metapart);
manager->post(request,multipart);

发送文件直接发QByteArray

数据会发送到body中,用request.body取

byte = request.body
file = open(os.path.join(文件路径+名称,"wb+"))
file.write(byte)
file.close()

发送文件

转载链接
我没有写上传普工表单的部分,直接写的上传文件可以,不知道有什么影响
简单的例子:
头文件

#ifndef HTTPPOSTFILE_H
#define HTTPPOSTFILE_H

#include <QHttpMultiPart>
#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QNetworkReply>
#include <QNetworkRequest>

QT_BEGIN_NAMESPACE
namespace Ui {
class HttpPostFile;
}
QT_END_NAMESPACE

class HttpPostFile : public QMainWindow
{
    Q_OBJECT

public:
    HttpPostFile(QWidget *parent = nullptr);
    ~HttpPostFile();
    void startPost();

public slots:
    void finished(QNetworkReply *);
    void finished();

private slots:
    void on_pushButton_clicked();

private:
    Ui::HttpPostFile *ui;
    QNetworkReply *reply;
    QNetworkAccessManager *manager;
};
#endif // HTTPPOSTFILE_H

cpp文件:

#include "HttpPostFile.h"
#include "ui_HttpPostFile.h"
#include <QDebug>
#include <QFile>
#include <QUuid>

HttpPostFile::HttpPostFile(QWidget *parent) : QMainWindow(parent), ui(new Ui::HttpPostFile)
{
    ui->setupUi(this);
    manager = new QNetworkAccessManager();
}

HttpPostFile::~HttpPostFile()
{
    delete ui;
}

void HttpPostFile::startPost()
{
    QString BOUNDARY = QUuid::createUuid().toString();
    QNetworkRequest request = QNetworkRequest(QUrl("http://127.0.0.1:8111/blog/uploadfile"));
    QFile *file = new QFile("C:\\Users\\hp\\Desktop\\cailiao\\4.jpg");
    file->open(QIODevice::ReadOnly);
    QByteArray sb = QByteArray();
    sb.append("--" + BOUNDARY + "\r\n");
    sb.append(QString("Content-Disposition: form-data;name=\"") + "myfile"
              + QString("\";filename=\"") + "45.jpg" + QString("\"") + QString("\r\n"));
    sb.append("\r\n");
    sb.append(file->readAll());

    sb.append("\r\n");

    sb.append("--" + BOUNDARY + "\r\n");

    request.setRawHeader(QString("Content-Type").toLatin1(),
                         QString("multipart/form-data;boundary=" + BOUNDARY).toLatin1());
    request.setRawHeader(QString("Content-Length").toLatin1(),
                         QString::number(sb.length()).toLatin1());

    reply = manager->post(request, sb);
    manager->get(request);
    connect(reply, SIGNAL(finished()), this, SLOT(finished()));
}

void HttpPostFile::finished(QNetworkReply *rp)
{
    qDebug() << rp->readAll();
}

void HttpPostFile::finished()
{
    QNetworkReply *rp = qobject_cast<QNetworkReply *>(sender());
    qDebug() << rp->readAll();
}

void HttpPostFile::on_pushButton_clicked()
{
    startPost();
}

//注:还是用Qt写好一点,把那些烦人的创建socket请求全都封装好了。c++真是麻烦。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值