前一段时间开发一个WebDAV的客户端,主要是接受发送文件。因为只需要上传下载文件,所以不想使用curl这样重量级的库,所以,基于以上原因自己编写封装一个类,利用socket完成对文件的上传和下载,还可以使用内核函数sendfile实现文件上传时的“零拷贝”。在本例中,同样也给出使用curl方式对文件进行上传操作的方法。针对WebDav的开发还有一个专门的库neon,同样这里也给出使用neon库完成文件上传操作的方法。
在上传过程中会把大于 2M 的文件,按 2M 发送,以防止,当上传文件过大时并且数量过多时,不能及时对其他非文件处理操作请求做出处理。
具体项目说明如下
USocket类(USocket.h和USocket.cc),创建到远程Web server的本地socket连接,它需要远程的host和port参数,这俩个参数可以从UUri类中获得。
UUri类(UUri.h和UUri.cc),传递给该类一个URL,比如http://www.exuetang.net:8080/test/test.jpg,该类会把此URL分解为scheme,host,port,path等信息
Putfile类(Putfile.h和Putfile.cc),上传文件操作类,通过putfile方法,需要webPath和本地文件的path,返回操作状态,以及文件大小。
调用方法
#include using namespace::std; #include "Putfile.h" #define FILENAME "/tmp/file/1.8m.JPG" using namespace::ucs; /* 上传文件 */ void putfile(const string& webPath, const string& filename) { Putfile client; int fileSize; // 上传文件 UState state = client.putfile(webPath,filename,fileSize); if(state == U_OK) cout << filename << " -- OK, file size " << fileSize << endl; else cout << filename << " -- fail" << state << endl; } int main ( int argc, char *argv[] ) { if(argc != 3) { cout << "./Client method /n"; cout << " ./Client webPath fileName/n"; return 0; }else{ string strWeb = argv[1]; string strFile = argv[2]; putfile(strWeb,strFile); } return EXIT_SUCCESS; }执行make命令,然后
./Client http://www.xxx.com/test.dat test.dat
输出如下的logPutfile.cc/_sectsendfile[348]: end recv 3784 Putfile.cc/_sectsendfile[351]: send file size: 114688 Putfile.cc/putfile[137]: put file OK Putfile.cc/putfile[140]: send size 114688| file size 160650 USocket.cc/~USocket[33]: USocket::~USocket() UUri.cc/~UUri[28]: UUri::~UUri /tmp/example/abc.jpg -- OK, file size 160650 Putfile.cc/~Putfile[52]: Putfile::~Putfile()
如果不使用sendfile,使用neon库或者curl库,需要修改Makefile文件,增加-lneon或者-lcurl库,同时修改Macros.h文件。如果不想显示日志,注释掉Logging.h文件中的
#define DEBUG_MODE