开发环境:
宿 主 机:window XP;
虚 拟 机:ubuntu9.10;
交叉编译器:arm-uclibc-gcc(arm-linux-gcc-4.3.2可以顺利编译通过)
———————————————————————————————————————————————————————————————————
1. 说明
最近调试web文件上传到服务器功能,但在调试时,处理函数总是获取不到文件路径,百思不得其解,查了网上许多文章,但大多提到的是前端文件上传的原理、实现方式等,而未提供服务器端处理的实现(利用C函数实现)。此外,由于对web不了解,花了些时间研究web程序。
2. goAhead实现文件上传的方法
总得来说,goAhead上实现文件上传功能是比较容易的。因为有现成的代码可用,稍微移植下即可。
2.1 实现原理
使用html form即表单提交文件上传请求,web服务器核心处理接收客户端Post过来的文件数据(注意post的是二进制数据),最后,web服务器把接收到文件数据以二进制格式写到服务器本端存储系统。
2.2 前端设计
前端设计比较简单,就是设计一个form,type属性为file,本人是在goAhead-2.5附带的wwwdemo的asptest.asp网页上增加了一个这样的form。
<!- Copyright (c) Go Ahead Software Inc., 1999-2010. All Rights Reserved. -><!-- del by gyr 2011.10.15 <title>ASP Test Page</title><title> new document </title><!-- add by gyr 2011.10.15 --><linkrel="stylesheet"href="/style/normal_ws.css"type="text/css"><% language=javascript %>function uploadFileSubmit() { // alert(document.getElementById("document.softupdate")); return; } <h1>ASP / JavaScript? Test</h1><h2>Expanded ASP data: <% aspTest("Peter Smith", "112 Merry Way"); %></h2> for (z=0; z<5; zz=z+1) \ { \ write(z+" is less than 3<br>"); \ write(z+" is equal to 3<br>"); \ else \ write(z+" is greater than 3<br>"); \ } \ <spanstyle="color:#3333ff;"><!-- added start for test upload file by gyr 2011.10.15 --><h1>GoForm upload file test</h1><formid="softupdate"action=/goform/formUploadFileTest method=POSTenctype="multipart/form-data"> Select file: <td><inputid="fileupload"type="file"size=60value=""></td><td><inputid="fileuploadsubmit"type="submit"value="update"></td><!-- added end for test upload file by gyr 2011.10.15 -->
其中,enctype参数用来设置表单的MIME编码方式,在进行文件(或同时包含文本框)上传时,必须将其属性设置为"multipart/form-data";formUploadFileTest 是web服务器定义的一个处理函数,用于把web服务器接收到的上传文件数据写到存储系统。
2.3 goAhead增加文件上传功能
goAhead-2.5的源码中,是没有包含文件上传功能的,因此需要对goAhead-2.5增加文件上传功能。本人使用v2.1.1版本的补丁,可从下载:http://download.csdn.net/detail/reille/3687321
打补丁的时候不是很方便,需要利用对比工具,把文件上传功能的源码增加到goAhead-2.5中。
2.4 把上传文件写到存储系统
在goAhead-2.5的源码main.c中增加文件上传form的处理函数:formUploadFileTest (),代码如下:
/******************************************************************************/ * for test html upload file to web serverstaticvoid formUploadFileTest(webs_t wp, char_t *path, char_t *query) { char_t * fn; char_t * bn = NULL; printf("\n...................formUploadFileTest...................\n\n"); a_assert(websValid(wp)); websHeader(wp); fn = websGetVar(wp, T("filename"), T("")); if (fn != NULL && *fn != '\0') { if ((int)(bn = gstrrchr(fn, '/') + 1) == 1) { if ((int)(bn = gstrrchr(fn, '\\') + 1) == 1) { bn = fn; } } } printf("fn=%s, bn=%s .......\n", fn, bn); websWrite(wp, T("Filename = %s<br>Size = %d bytes<br>"), bn, wp->lenPostData); if ((fp = fopen((bn == NULL ? "upldForm.bin" : bn), "w+b")) == NULL) { websWrite(wp, T("File open failed!<br>")); locWrite = 0; numLeft = wp->lenPostData; numWrite = fwrite(&(wp->postData[locWrite]), sizeof(*(wp->postData)), numLeft, fp); if (numWrite < numLeft) { websWrite(wp, T("File write failed.<br> ferror=%d locWrite=%d numLeft=%d numWrite=%d Size=%d bytes<br>"), ferror(fp), locWrite, numLeft, numWrite, wp->lenPostData); } locWrite += numWrite; numLeft -= numWrite; } websWrite(wp, T("File close failed.<br> errno=%d locWrite=%d numLeft=%d numWrite=%d Size=%d bytes<br>"), errno, locWrite, numLeft, numWrite, wp->lenPostData); websWrite(wp, T("File Size Written = %d bytes<br>"), wp->lenPostData); } websWrite(wp, T("numLeft=%d locWrite=%d Size=%d bytes<br>"), numLeft, locWrite, wp->lenPostData); } } websFooter(wp); websDone(wp, 200); }
3. 资料
3.1 http://blog.csdn.net/reille/article/details/6871827 本博客转载的文章
3.2 http://www.hackchina.com/r/57970/v2.1.1-_-web-_-upload.htm__html 前端实现参考
3.3 http://www.hackchina.com/r/57970/v2.1.1-_-LINUX-_-upldForm.c__html 服务器端实现参考