首先由内容阻止所有文件(块大小的约束),然后对于每一个chunk构造单独的一个UDP 数据报进行传输,在应用层的開始是自己定义的包头,有块号,块长度,块指纹等元数据信息,这些信息便于接收端可以按序正确接收。

/*--vonzhou
---this project is to upload file after chunking using
rabin fingerprint, here use UDP so that every packet nodelay.
but we need to ensure the reliability. */ #include "global.h" #define SERV_PORT 2500 typedef struct {
unsigned char fp[20];
int chunk_id;
short flags;
short chunk_len; // The max is 32767 enough
char data[MAX_CHUNK_SIZE];
}TransferUnit; // some flags for this chunk transfered.
enum{
CHUNK_NEED_DEDU = 0x0001, // need deduplication
CHUNK_OTHER = 0x0002 // other for extension
}; FileInfo *fi; int sendUDP(FileInfo *fi,int sockfd,struct sockaddr *pservaddr,socklen_t servlen){
char buf[sizeof(TransferUnit)];
fd_set wrset;
struct timeval tv;
int rlen,wlen, len = 1;
int fd;
int ret;
int i,j;
FingerChunk *p;
TransferUnit unit; //connect to server
if(connect(sockfd,(struct sockaddr *)pservaddr,servlen) == -1)
err_quit("connet error");
else
printf("connect server ok!\n"); fd = open(fi->file_path, O_RDONLY);
if(fd==-1)
err_quit("fopen error %s\n",strerror(errno)); // begin to transfer the file to the server;
i=0;
p = fi->first; while(1){
tv.tv_sec = 1;// tell select to wait 1 second;
tv.tv_usec = 0; FD_ZERO(&wrset);
FD_SET(sockfd,&wrset);
// wait for the socket can write
ret = select(sockfd+1,NULL,&wrset,NULL,&tv);
if(ret == -1)
err_quit("select error %s\n",strerror(errno));
else if(ret==0){
printf("select timeout,continue circle\n");
continue;
} //prepare for writing the socket
memset(&unit, 0, sizeof(unit));
if(FD_ISSET(sockfd,&wrset)){
/* we should first transfer some medadata,like filename,filter feature vector,
*FIXME: file fingerprint to controller? to make a packetin,
*here just let the fp = 20 1s
*/
if(i == 0){
for(j=0;j<20;j++)
unit.fp[j] = 0xff;
unit.chunk_id = 0;
//need not dedu
unit.chunk_len = strlen(fi->file_path);
wlen = write(sockfd, &unit, 28 + strlen(fi->file_path));
if(wlen != (28 + strlen(fi->file_path)))
err_quit("write data to sockfd error:%s\n",strerror(errno));
memset(&unit, 0, sizeof(unit));
} if(p != NULL)
len = p->chunklen;
// the last read , p is null, so cannnot use p->chu
rlen = read(fd, unit.data, len);
if(rlen < 0)
err_quit("fread data error %s\n",strerror(errno));
else if(rlen==0){
//indicate the transfer completed
for(j=0;j<20;j++)
unit.fp[j] = 0xff;
unit.chunk_id = 0;
//need not dedu
unit.chunk_len = 3;
strncpy(unit.data,"end", 3);
wlen = write(sockfd,&unit,28 + 3);
if(wlen !=31)
err_quit("write end flag error:%s\n",strerror(errno)); printf("File %s Transfer Success!\n", fi->file_path);
close(fd);
return 0;
}
// construct this tranfer unit we cannot before read
//bcos the following p pointer used.
for(j=0; j< 20;j++)
unit.fp[j] = p->chunk_hash[j];// 20B fingerprint;
unit.chunk_id = i; // 4B chunk ID
unit.chunk_len = p->chunklen;
unit.flags = CHUNK_NEED_DEDU;
//write to socket
wlen = write(sockfd, &unit, 28+p->chunklen);
if(wlen != (rlen + 28))
err_quit("write data to sockfd error:%s\n",strerror(errno)); i++;
p = p->next;
memset(&unit, 0, sizeof(unit));
usleep(500);
printf("The %d times read\n",i);
}
}// end while(1)
} int main(int argc ,char *argv[])
{
char *fh;
struct sysinfo s_info;
long time1,time2;
int error1,error2;
int sockfd;
struct stat fsize;
struct sockaddr_in servaddr;
error1= sysinfo(&s_info);
time1 = s_info.uptime;
int r;
// FileInfo *fi;
fi = file_new(); if(argc != 3)
err_quit("useage:udpclient<IPaddress>;\n");
bzero(&servaddr,sizeof(servaddr));
servaddr.sin_family= AF_INET;
servaddr.sin_port = htons(SERV_PORT); if(inet_pton(AF_INET,argv[1],&servaddr.sin_addr) <= 0)
err_quit("[%s]is not a valid IPaddress\n",argv[1]); sockfd =socket(AF_INET,SOCK_DGRAM,0); r = fcntl(sockfd, F_GETFL, 0);
fcntl(sockfd, F_SETFL, r & ~O_NONBLOCK); // chunking file
strcpy(fi->file_path, argv[2]);
chunk_file(fi);
printf("File size : %lld\n",fi->file_size);
printf("Chunk Num : %d\n",fi->chunknum); sendUDP(fi, sockfd, (struct sockaddr *)&servaddr,sizeof(servaddr));
close(sockfd); fprintf(stderr,"ServerIP:\t%s\n",argv[1]);
if(stat(argv[2],&fsize) == -1)
perror("failed to get fiel statusi\n");
else
fprintf(stderr,"file name:\t%s\nfile size:\t%dK\n",argv[2],fsize.st_size/1024);
error2=sysinfo(&s_info);
time2 = s_info.uptime;
printf("tranfice file time =%ld seconds\n",(time2-time1));
}

转载请注明出处:http://blog.csdn.net/vonzhoufz/article/details/31429585

版权声明:本文博客原创文章,博客,未经同意,不得转载。

上传文件块client实现的更多相关文章

  1. node 上传文件 http client to post file

    node做http client 发送post数据是很容易的事情,但要上传文件就不是太容易了主要是因为上传文件的报文和普通post是不太一样的 要了解http post可以看下这个 https://i ...

  2. OSS上传文件到阿里云

    最近做项目,需要上传文件,因为上传到项目路径下,感觉有时候也挺不方便的,就试了一下上传文件到阿里云oss上去了, oss的使用网上有很多介绍,都是去配置一下需要的数据,然后直接调用他的api就可以了. ...

  3. PHP上传文件超过了最大文件大小限制导致无法上传成功

    最近的研究<HeadFirst PHP & MySQL>第一本书5章"使用存储在文件中的数据",难道当一个文件上传应用程序,发生了错误.即,文件不能成功上传.这 ...

  4. C 上传文件到服务器(含接收端源码)

    本文demo下载地址:http://www.wisdomdd.cn/Wisdom/resource/articleDetail.htm?resourceId=1067 实例向大家展示了如何用Visua ...

  5. HDFS上传文件

    1.client端向namenode请求上传文件,查看文件是否存在,是否有权限往hdfs写入 2.如果文件不存在,权限OK就根据副本数N(例如2个),根据网络拓扑选择N个离client端最近的data ...

  6. 4 django系列之HTML通过form标签来同时提交表单内容与上传文件

    preface 我们知道提交表单有2种方式,一种直接通过submit页面刷新方法来提交,另一种通过ajax异步局部刷新的方法提交,上回我们说了通过ajax来提交文件到后台,现在说说通过submit来提 ...

  7. PHP socket上传文件图片

    最近了解了下下socket方面的东西,想做一个socket上传文件的例子. 在网上搜了搜代码执行后,图片数据传输了一半,图片的下半部分是灰色的.然后就自己仿着搜来的代码和php.net 中socket ...

  8. WPF上传文件到服务器

    利用WebClient 上传文件到服务器 创建一个空网站,创建一个UploadFile.aspx项, 服务器报500错误:检查文件保存路径是否存在,检查文件大小限制 protected void Pa ...

  9. 通过Ajax使用FormData对象无刷新上传文件

    写在前面:本文说的这个方案有浏览器兼容性问题:所有主流浏览器的较新版本已经支持这个对象了,比如Chrome 7+.Firefox 4+.IE 10+.Opera 12+.Safari 5+,对兼容性比 ...

随机推荐

  1. WPF-21:WPF实现仿安卓的图案密码键盘(初级)

    希望大家有这方面好的代码给提供下,谢谢了! 想用C#做一个和手机上一样的图形密码键盘,貌似这方面资料比较少,虽然winphone手机上也有但是网上也没有这方面的代码.只好用常规的思维去实现一下,当然是 ...

  2. Android中TextView中内容不换行的解决方法

    问题 如果新建的Android项目采用的Android 3.0以上的SDK,同时采用了 <style name="AppTheme" parent="@androi ...

  3. 使用Sublime Text 2编辑和运行node-webkit应用程序

    开发工具目录结构 --E:\develop\ ----node-webkit-v0.9.2-win-ia32 ----Sublime Text 2.0.2 x64 为Sublime text2构建Bu ...

  4. windows phone 使用相机并获取图片(3)

    原文:windows phone 使用相机并获取图片(3) 使用相机需要引用如下命名空间 " Margin="12,10,12,0" ></Image> ...

  5. osgi实战学习之路:3. osgi分层概念及相互合作demo

    源码下载 分层: modual: 主要作用于包级管理与共享代码 lifecycle: 主要作用于执行期间的模块管理与訪问osgi底层框架 service: 主要作用于多模块之间的相互通信 demo: ...

  6. Emacs经常使用快捷键的注意事项

    一直用VIM,尝试了好几次Emacs都被它"多得像天上的星星"一样的快捷键给吓倒了.这几天最终下定决心再次尝试. 将它的Tutor练习了一下,顺便对经常使用快捷键做了一下笔记,方便 ...

  7. Array of Objects

    You should be comfortable with the content in the modules up to and including the module "Array ...

  8. Linux命令对应的全称解释(转)

    Filesystem Hierarchy Standard(FHS) /:根目录,所有的目录.文件.设备都在/之下,/就是Linux文件系统的组织者,也是最上级的领导者.  /bin:bin 就是二进 ...

  9. [Elasticsearch] 邻近匹配 (三) - 性能,关联单词查询以及Shingles

    提高性能 短语和邻近度查询比简单的match查询在性能上更昂贵.match查询仅仅是查看词条是否存在于倒排索引(Inverted Index)中,而match_phrase查询则须要计算和比較多个可能 ...

  10. java实现代理domino web邮件下载

    [背景] 近日在研究domino web邮件下载功能,下载的邮件能够导入foxmail.outlook邮件client,下载的邮件格式为eml. [參考代码](须要下载jmail.jar包) priv ...