August 29, 2010 分类: ASM/C/C++     作者: hoverlees     留言: 发表

这个库是以前用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

我来留个言

您的电子邮箱我一定会保密的哦!

昵称

邮箱

评论内容