其他语言都比较方便,使用http上传。但是C++这样就差点,不过还好,Linux下有个curl的命令行工具,这是一个开源项目,底下有个子项目是libcurl,curl就是调用这个API实现的一系列ftp,http等上传下载的功能,这个库功能还是挺多的。支持的协议也多。这样就可以利用这个库来实现http上传和下载了。
当然这个库的API有两种接口,一种是esay的-------同步阻塞模式。另一种是Multi的,我没研究它,以下用的都是easy的接口,来写的样例代码。
不过在学这个库的接口之前,最好先了解下http,特别是GET和POST方法的区别,这两个方法前者涉及到对URL的查询,后者涉及到对URL的改写。当然GET和POST都可以向server传输数据。并不能根据它们的名字直接理解,详情请看http协议吧。我找了两个不错的博客连接,来理解http相关的内容,非常不错,写得很好:
http://www.cnblogs.com/devil-91/archive/2012/05/11/2495266.html
http://www.cnblogs.com/hyddd/archive/2009/03/31/1426026.html
文件上传类:
H文件:
#ifndef QCURL_SENDER_H
#define QCURL_SENDER_H
#include <string>
#include <curl/curl.h>
class CurlSender{
public:
CurlSender();
~CurlSender();
bool isValid() const;
void setUrl(const std::string& url);
bool send(const std::string &file);
private:
std::string getFileNameFromPath(const std::string& path);
private:
CURL* m_hCurl;
std::string m_url;
bool m_isValid;
};
#endif
.cpp文件
#include "QCurlSender.h"
CurlSender::CurlSender():
m_hCurl(nullptr), m_isValid(false)
{
curl_global_init(CURL_GLOBAL_ALL);
m_hCurl = curl_easy_init();
if (m_hCurl)
{
m_isValid = true;
}
}
CurlSender::~CurlSender()
{
if (m_hCurl)
{
curl_easy_cleanup(m_hCurl);
}
curl_global_cleanup();
}
bool CurlSender::isValid() const
{
return m_isValid;
}
void CurlSender::setUrl(const std::string& url)
{
m_url = url;
}
bool CurlSender::send(const std::string &file)
{
curl_slist* pOptionList = NULL;
pOptionList = curl_slist_append(pOptionList, "Expect:");
curl_easy_setopt(m_hCurl, CURLOPT_HTTPHEADER, pOptionList);
curl_httppost* pFormPost = NULL;
curl_httppost* pLastElem = NULL;
//上传文件,指定本地文件完整路径
curl_formadd(&pFormPost, &pLastElem, CURLFORM_COPYNAME, "sendfile",
CURLFORM_FILE, file.c_str(), CURLFORM_CONTENTTYPE,
"application/octet-stream", CURLFORM_END);
curl_formadd(&pFormPost, &pLastElem,
CURLFORM_COPYNAME, "filename",
CURLFORM_COPYCONTENTS, getFileNameFromPath(file).c_str(),
CURLFORM_END);
//不加一个结束的hfs服务端无法写入文件,一般不存在这种问题,这里加入只是为了测试.
curl_formadd(&pFormPost, &pLastElem, CURLFORM_COPYNAME, "end", CURLFORM_COPYCONTENTS, "end", CURLFORM_END);
curl_easy_setopt(m_hCurl, CURLOPT_HTTPPOST, pFormPost);
curl_easy_setopt(m_hCurl, CURLOPT_URL, m_url.c_str());
CURLcode res = curl_easy_perform(m_hCurl);
if (res != CURLE_OK)
{
return false;
}
curl_formfree(pFormPost);
return true;
}
std::string CurlSender::getFileNameFromPath(const std::string& path)
{
return path.substr(path.find_last_of("/\") + 1);
}
http下载类:
H文件:
1 #ifndef TASK_HTTP_RECVER_H
2 #define TASK_HTTP_RECVER_H
3
4 #include <curl/curl.h>
5 #include <string>
6 #include <cstdio>
7
8 class HttpRecver {
9
10
11 public:
12 HttpRecver();
13 ~HttpRecver();
14
15 bool isValid() const;
16 void setUrl(const std::string& url);
17 void setSavePath(const std::string &path);
18
19
20
21
22 private:
23 bool recv();
24 //下载回调函数
25 static size_t DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam);
26 std::string getFileNameFromPath(const std::string& path);
27
28 private:
29 FILE *m_fp;
30 CURL* m_hCurl;
31 std::string m_url;
32 std::string m_savePath;
33 std::string m_filename;
34 bool m_isValid;
35 bool m_bReady;
36
37 };
38
39 #endif
View Code
cpp文件:
1 #include "TaskHttpRecver.h"
2
3 HttpRecver::HttpRecver() :
4 m_isValid(false), m_hCurl(nullptr), m_fp(nullptr)
5 {
6
7 LOG_(LOGID_DEBUG, LOG_F("Entry HttpRecver()"));
8
9 curl_global_init(CURL_GLOBAL_ALL);
10 m_hCurl = curl_easy_init();
11
12 if (m_hCurl)
13 {
14 m_isValid = true;
15 }
16
17 LOG_(LOGID_DEBUG, LOG_F("Entry HttpRecver()"));
18 }
19
20 HttpRecver::~HttpRecver()
21 {
22 LOG_(LOGID_DEBUG, LOG_F("Entry ~HttpRecver()"));
23
24 if (m_hCurl)
25 {
26 curl_easy_cleanup(m_hCurl);
27 }
28
29 curl_global_cleanup();
30
31 LOG_(LOGID_DEBUG, LOG_F("Leave ~HttpRecver()"));
32 }
33
34 bool HttpRecver::isValid() const
35 {
36 return m_isValid;
37 }
38
39 void HttpRecver::setUrl(const std::string& url)
40 {
41 m_url = url;
42 m_filename = getFileNameFromPath(m_url);
43 }
44
45 void HttpRecver::setSavePath(const std::string &path)
46 {
47 m_savePath = path;
48 }
49
50 std::string HttpRecver::getFileNameFromPath(const std::string& path)
51 {
52 return path.substr(path.find_last_of("/\") + 1);
53 }
54
55 bool HttpRecver::recv()
56 {
57 curl_easy_setopt(m_hCurl, CURLOPT_URL, m_url.c_str());
58
59 std::string filePath = m_savePath + m_filename;
60
61 m_fp = fopen(filePath.c_str(), "wb");
62
63 if (!m_fp)
64 {
65 return false;
66 }
67
68 //设置接收数据的回调
69 curl_easy_setopt(m_hCurl, CURLOPT_WRITEFUNCTION, DownloadCallback);
70 curl_easy_setopt(m_hCurl, CURLOPT_WRITEDATA, m_fp);
71 curl_easy_setopt(m_hCurl, CURLOPT_MAXREDIRS, 5);
72 curl_easy_setopt(m_hCurl, CURLOPT_FOLLOWLOCATION, 1);
73
74 CURLcode retcCode = curl_easy_perform(m_hCurl);
75
76 if (retcCode != CURLE_OK)
77 {
78
79 fclose(m_fp);
80 m_fp = nullptr;
81 return false;
82 }
83
84 fclose(m_fp);
85 m_fp = nullptr;
86
87 return true;
88 }
89
90 size_t HttpRecver::DownloadCallback(void* pBuffer, size_t nSize, size_t nMemByte, void* pParam)
91 {
92 FILE* fp = (FILE*)pParam;
93 size_t nWrite = fwrite(pBuffer, nSize, nMemByte, fp);
94
95 return nWrite;
96 }
View Code
references:
http://www.cnblogs.com/cswuyg/archive/2013/07/11/3185164.html
http://www.cnblogs.com/lidabo/p/4159574.html
http://blog.csdn.net/breaksoftware/article/details/45874197
http://stackoverflow.com/questions/8520560/get-a-file-name-from-a-path
http://blog.csdn.net/mfcing/article/details/43051865
http://blog.csdn.net/infoworld/article/details/46646933
原文链接: https://www.cnblogs.com/foohack/p/4955392.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/224383
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!