这个库是以前用MASM32的时候写的,它的功能其实就是实现multipart/form-data的标准的方式去与HTTP WebServer交互。只是这个库是纯socket实现的模拟浏览器表单提交,包含提交文件的功能。
首先要承认,做这个库的时候,我没有去看相关的规范文档,而是截获的IE提交表单的数据包来分析,然后再用socket直接封装的这个库。Multipart的form其它字段跟post的也差不多,而上传文件的时候是用一个界限字符串来区分文件。我一直在想,如果文件是一个文本文件,文本文件里恰好又包含这个boundary的结束标记,那会出现什么情况呢。呵呵,当然,我的boundary标记是随机生成的,所以基本上是不大可能与文本文件里有相同的字符串,有就不知道是什么结果了。总之我觉得我们不用太关注这种基本上不可能发生的小概率事件。
有了这个库,应用程序就可以实现跟浏览器一样的向webserver上传文件功能了。
使用方法,我发布的C头文件里写得很详细:
/****************************** 表单提交模块(C头文件) BY HOVERLEES. me[at]hoverlees.com ******************************/ //以下常量为表单类型 #define FORMTYPE_TEXT 1 //该条目为类似于HTML表单的<input type="text">,<input type="radio">,<textarea>类型,即文本类型。 #define FORMTYPE_FILE 2 //该条目为类似于HTML表单的<input type="file">类型。 //以下常量表示表单的编码 #define ENCODING_GBK 1 #define ENCODING_GB2312 1 #define ENCODING_UTF8 2 /** 例子: 1.定义回调函数: int MyFormControl(DWORD status,DWORD posted,DWORD total){ if(status==0){ printf("传输超时"); return false; } //计算已完成的百分比 float f=posted/total; //将百分比输出到想输出的地方 return 1; //返回true继续操作。 } ..... 2.主程序 //使用库之前需要调用WSAStartup,必须!!!!!!!!!!!!!! void main(){ WSAStartup(0x202,&wsadata); DWORD hForm=InitMultipartForm(ENCODING_UTF8,"localhost","/upload.php",&MyFormControl); MFAddFormItem(hForm,FORMTYPE_TEXT,"name","hoverlees"); //<input type="text" name="name" value="hoverlees"> MFAddFormItem(hForm,FORMTYPE_FILE,"file","C:/a.rar"); MFPostForm(hForm); FreeMultipartForm(hForm); WSACleanUp(); } //库每上传一个数据包,都会调用回调函数,提供状态信息,回调函数可以返回1以继续或0以停止上传. */ /** InitMultipartForm 初始化表单。 参数: formEncoding 为ENCODING_GBK或ENCODING_UTF8 pHost 主机名,如www.hoverlees.com,www.yahoo.com.cn等。 pObjectName 提交的页面,如/submit.php,/dir/dir2/submit.php。 pCallback 回调函数,表单每提交一点数据就调用此函数。并且此函数可以控制表单的上传。 回调函数格式: int MFCallback(DWORD status,DWORD posted,DWORD total) status:如果是1,表示正在正常传输,如果是0,表示网络超时。 posted:已发送字节 total:总共要发送的字节。 返回:如果要继续上传,必须返回1,如果要中止上传,返回0 返回:表单句柄。 */ DWORD WINAPI InitMultipartForm(DWORD formEncoding,LPSTR pHost,LPSTR pObjectName,LPVOID pCallback); /** MFAddFormItem 向表单加入元素。 参数: hForm 表单句柄 itemType 元素类型 pItemName 元素名称 pData 元素内容。如果itemType是FORMTYPE_TEXT,则此pData指向内容字符串,如果是FORMTYPE_FILE,则pData指向文件名。 */ DWORD WINAPI MFAddFormItem(DWORD hForm,DWORD itemType,LPSTR pItemName,LPVOID pData); /** MFPostForm 提交表单 参数: hForm 表单句柄 返回: 与服务器连接的套接字句柄 (SOCKET)。 如果要读取服务器的返回信息,调用recv函数。 必须关闭这个返回的句柄 closesocket */ DWORD WINAPI MFPostForm(DWORD hForm); /** MFPostForm 释放表单 参数: hForm 表单句柄 */ DWORD WINAPI FreeMultipartForm(DWORD hForm);
下载库及C和MASM32示例MultiForm.tar