http上传文件 pda java_通过HTTP协议上传文件
HTTP是很常见的协议,虽然用得很多,但对细节的了解却是很浅,这回通过向服务端上传文件信息来理解细节。网络库的选择:1、WinHTTP是windows下常用的库;2、CURL是广受喜爱的开源库。对于我来说,libcurl最大的优点是使用方便,可以把注意力更多的集中到业务层上,提高工作效率,避免重造轮子;缺点是略大(MD编译有264KB,MT编译有340KB),不像WinHTTP可以由windows操作系统集成。下边展示如何使用这两种网络库实现表单POST文件。
一、libcurl
库编译:把include、lib的代码拿出来,使用静态库,设置预定义宏BUILDING_LIBCURL。
测试工程:设置预定义宏CURL_STATICLIB;添加依赖lib:Ws2_32.lib Wldap32.lib。
主要代码:
voidcurl_post_cswuyg()
{
curl_global_init(CURL_GLOBAL_ALL);
CURL* hCurl =curl_easy_init();if(hCurl !=NULL)
{//也许有Expect: 100-continue,去掉它
curl_slist* pOptionList =NULL;
pOptionList= curl_slist_append(pOptionList, "Expect:");
curl_easy_setopt(hCurl, CURLOPT_HTTPHEADER, pOptionList);
curl_httppost* pFormPost =NULL;
curl_httppost* pLastElem =NULL;//上传文件,指定本地文件完整路径
curl_formadd(&pFormPost, &pLastElem, CURLFORM_COPYNAME, "ufile01", CURLFORM_FILE, "C:\\temp\\upload_test_curl_cswuyg.txt", CURLFORM_CONTENTTYPE, "application/octet-stream", CURLFORM_END);//上传自定义文件内容的文件,CURLFORM_BUFFER指定服务端文件名//http://curl.haxx.se/libcurl/c/curl_formadd.html
char* file_info = "file_info——cswuyg";int record_length = std::string(file_info).length();
curl_formadd(&pFormPost, &pLastElem,
CURLFORM_COPYNAME,"ufile01",
CURLFORM_BUFFER,"cswuyg_test.txt",
CURLFORM_BUFFERPTR, file_info,
CURLFORM_BUFFERLENGTH, record_length,
CURLFORM_END);//不加一个结束的hfs服务端无法写入文件,一般不存在这种问题,这里加入只是为了测试.//curl_formadd(&pFormPost, &pLastElem, CURLFORM_COPYNAME, "end", CURLFORM_COPYCONTENTS, "end", CURLFORM_END);
curl_easy_setopt(hCurl, CURLOPT_HTTPPOST, pFormPost);
curl_easy_setopt(hCurl, CURLOPT_URL,"http://127.0.0.1/hfs_up/");
CURLcode res=curl_easy_perform(hCurl);if(res !=CURLE_OK)
{
std::wcout<< "Error" <<:endl>
}
curl_formfree(pFormPost);
curl_easy_cleanup(hCurl);
}
curl_global_cleanup();
}
wireshark抓包,127.0.0.1地址无法抓到,网络上有解决方案。示意图:
头域设置分割符:
MIME部分:
二、WinHTTP
库:winhttp.lib
主要代码:
voidcswuyg_winhttp_post()
{
HINTERNET hSession= ::WinHttpOpen(L"cswuyg post test/1.0", WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, NULL);
HINTERNET hConnect= ::WinHttpConnect(hSession, L"127.0.0.1", INTERNET_DEFAULT_HTTP_PORT, 0);if (hConnect ==NULL)
{int i =ERROR_WINHTTP_INCORRECT_HANDLE_TYPE;return;
}const wchar_t* lpszAcceptedType[] = {L"*/*", NULL};
HINTERNET hRequest= ::WinHttpOpenRequest(hConnect, L"POST", L"hfs_up", L"HTTP/1.1", WINHTTP_NO_REFERER, lpszAcceptedType, 0);if (hRequest ==NULL)
{return;
}
DWORD dwTime= 5000;
::WinHttpSetOption(hRequest, WINHTTP_OPTION_CONNECT_TIMEOUT,&dwTime, sizeof(DWORD));
std::wstring strHeader= L"Content-Type: multipart/form-data; boundary=--boundary_cswuygtest\r\n";
::WinHttpAddRequestHeaders(hRequest, strHeader.c_str(), strHeader.length(), WINHTTP_ADDREQ_FLAG_ADD|WINHTTP_ADDREQ_FLAG_REPLACE);
std::string strMIME = "----boundary_cswuygtest\r\n";
strMIME+= "Content-Disposition: form-data; name=\"ufile01\"; filename=\"upload_test_http_cswuyg.txt\"\r\n";
strMIME+= "Content-Type:application/octet-stream\r\n\r\n";
strMIME+= "1\r\n";/
//除了这个表单之外,后头还必须要有另外的表单信息,否则hfs服务端那边无法写入文件,这里仅为测试。//strMIME += "----boundary_cswuygtest\r\n" ;//strMIME += "Content-Disposition: form-data; name=\"name\"\r\n\r\n";//strMIME += "temp.txt\r\n";
/
strMIME += "----boundary_cswuygtest--\r\n";/
//可以直接写入//::WinHttpSendRequest(hRequest, strHeader.c_str(), strHeader.length(), (LPVOID)strMIME.c_str(), strMIME.length(), strMIME.length(), 0);//也可以后面分步写入
::WinHttpSendRequest(hRequest, NULL, 0, NULL, 0, strMIME.length(), 0);
DWORD dwWritten= 0;while(!strMIME.empty())
{
::WinHttpWriteData(hRequest, strMIME.c_str(), strMIME.length(),&dwWritten);if (strMIME.length() >dwWritten)
{
strMIME.substr(dwWritten);
}else{
strMIME= "";
}
}
::WinHttpReceiveResponse(hRequest, NULL);char buf[1024] = { 0};
DWORD dwToRead= 1024;
DWORD dwHaveRead= 0;
::WinHttpReadData(hRequest, buf, dwToRead,&dwHaveRead);
std::cout<< buf <<:endl>
::WinHttpCloseHandle(hRequest);
::WinHttpCloseHandle(hConnect);
::WinHttpCloseHandle(hSession);
}
wireshark抓包:
头域设置:
表单设置:
三、总结
这两个例子用hfs做服务器测试可以发现在上传文件夹中上传了文件,代码都很简单。测试过程中的最重要的是能尽快的反馈结果,所以能自己搭建一个http服务器很重要,hfs工具,非常简单便捷。
POST表单最重要的是了解表单的格式。首先要在头域增加Content-Type说明,如:“content-type:multipart/from-data; boundary=--cswuyg”。然后http body填充的数据要以MIME格式上传,每部分数据的开头都是由“--”+boundary开始的,结尾以"--"+boundary+"--"结束。
如果要上传文件,需要跟服务器约定好格式,譬如上边例子约定在content-Disposition中有filename键的则是上传文件信息,该片的content为文件数据,这应该是比较通用的约定。
附上部分资料:
MIME:http://baike.baidu.com/view/160611.htm
MIME来源 : Multipurpose Internet Mail Extensions 多用途互联网邮件扩展。服务器会将它们发送的多媒体数据的类型告诉浏览器,而通知手段就是说明该多媒体数据的MIME类型。
GZIP文件:application/x-gzip
任意的二进制数据:application/octet-stream.
普通文本:text/plain
wireshark:
MIME Multipart Media Encapsulation 代表使用表单上传的所有数据
Encapsulated multipart part 代表表单中不同项的数据
Boundary 用来隔开表单中不同部分的数据
每部分数据的开头都是由“--”+boundary开始的。
如果使用wireshark抓包,而http使用的不是默认的80端口,那么需要抓TCP包,然后再强制Decode为http。
HTTP协议的文档:
chroimumde breakpad_sender代码中也有post表单上传文件部分,只不过它是用WinInet写的。
2015 补充上传文件时的抓包信息:
http上传文件 pda java_通过HTTP协议上传文件相关推荐
- c++判断ftp服务器文件存在性判断_BitTorrent协议与传统文件分发协议对比
一.文件传输 前端时间做了和文件传输相关的工作,今天抽空做个总结.总结一下平常使用的几种协议以及BtTorrent协议.其实BitTorrent协议也不是什么新协议,它诞生也十几年了.咱也蹭个热点,最 ...
- webuploader java_使用WebUploader实现上传文件功能(一)
写在前面: 文件上传方式很多的,对于大文件的上传,在本次项目中也有涉及,主要是用了分片断点上传大文件.所以就去了解了一下WebUploader,先从简单的上传文件开始吧. 在代码中写注释,这样看的比较 ...
- Python监控目录文件夹,并使用SFTP上传目录及文件到linux服务器
Python 扫描监控本地文件夹并进行超大文件上传 方案1:WebUploader大文件分块多线程并发上传 方案2:watchdog目录文件夹监控,paramiko STFP上传服务器 方案3:优化2 ...
- JSP中的文件操作:数据流、File类、文件浏览、目录操作、上传下载
文件可以永久地存储信息,从本质上讲文件就是存放在盘上的一系列数据的集合.应用程序如果想长期保存数据,就必须将数据存储到文件中,这就涉及到文件的操作.而在编写网站应用程序的过程中,有许多地方要对文件 ...
- php上传照片到s3云服务器,PHP上传文件到AWS S3生成下载文件URL
* 加载s3客户端 * @return string*/ functionAWS_S3Client(){$ACCESS_KEY_ID = '你的s3 ID';$SECRET_ACCESS_KEY = ...
- [C# 网络编程系列]专题十一:实现一个基于FTP协议的程序——文件上传下载器...
引言: 在这个专题将为大家揭开下FTP这个协议的面纱,其实学习知识和生活中的例子都是很相通的,就拿这个专题来说,要了解FTP协议然后根据FTP协议实现一个文件下载器,就和和追MM是差不多的过程的,相信 ...
- gz文件解压命令 linux_linux常用命令和文件上传(FZ)、解压、配置环境变量(JDK)
第141次(Linux) 学习主题:Linux 学习目标: 掌握Linux常用命令 一.Linux常用命令 1-cd命令 change directory – 切换目录 特殊目录符号 :当前目录 –' ...
- php ios视频文件上传,iOS实现视频和图片的上传思路
关于iOS如何实现视频和图片的上传, 我们先理清下思路,然后小编根据思路一步一步给大家详解实现过程. 思路: #1. 如何获取图片? #2. 如何获取视频? #3. 如何把图片存到缓存路径中? #4. ...
- 在Windows上使用终端模拟程序连接操作Linux以及上传下载文件
在Windows上使用终端模拟程序连接操作Linux以及上传下载文件 [很简单,就是一个工具的使用而已,放这里是做个笔记.] 刚买的云主机,或者是虚拟机里安装的Linux系统,可能会涉及到在windo ...
最新文章
- 如何配置IntelliJ IDEA发布JavaEE项目?
- 数据结构中几种经典排序简介
- tomcat1.8,tomcat-users.xml文件中如下修改才可以使用app manager登录,其中的roles有哪些枚举需要确认
- 独家 | 人工智能不能忽视符号逻辑以及原因
- VirtualBox下安装RHEL5.5+Oracle 11g手记
- JS中class和id的区别
- 在LINUX环境中,哪种文件系统存储更安全?
- Python之sklearn:GridSearchCV()和fit()函数的简介、具体案例、使用方法之详细攻略
- error LNK1123: 转换到 COFF 期间失败: 文件无效或损坏的解决方案
- UVa 1626 (输出方案) Brackets sequence
- 200801一阶段1函数封装
- 【汇总】flash单个文件上传
- 各大软件的 java版本_Java 各个版本的软件 1.4 1.5 5.0 6.0
- Web API框架学习——消息管道(二)
- LAMMPS分子动力学模拟技术与应用 第一性原理计算方法及应用
- python绘制单线图_教你快速利用CAD绘制管道单线图.pdf
- mysql安装依赖perl(Data::Dumper)
- 人生中最重要的是什么?
- 2018年最新Python学习路线图(内含大纲+视频+工具)
- 入职某厂安卓工程师的成长记录