其他语言都比较方便,使用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); }
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