上传文件块client实现

上传文件块client实现

大家好,又见面了,我是全栈君,今天给大家准备了Idea注册码。


首先由内容阻止所有文件(块大小的约束),然后对于每一个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

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

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/117349.html原文链接:https://javaforall.net

赞 (0)
全栈程序员-站长的头像全栈程序员-站长

相关推荐

  • java中中文显示乱码_java中显示中文乱码解决方法

    java中中文显示乱码_java中显示中文乱码解决方法java显示乱码解决方法:1、utf8解决JSP中文乱码问题一般说来在每个页面的开始处,加入:charset=UTF-8的作用是指定JSP向客户端输出的编码方式为“UTF-8”;pageEncoding=”UTF-8″,为了让JSP引擎能正确地解码含有中文字符的JSP页面,这在LINUX中很有效;request.setCharacterEncoding(“UTF-8”);是对请求进行了中文编码。有…

    2022年7月7日
  • QT中this指针

    QT中this指针一:this指针只能在一个类的成员函数中调用,它表示当前对象的地址。下面是一个例子: void Date::setMonth( int mn) { month=mn; // 这三句是等价的 this->month=mn; (*this).month=mn; }1.this只能在成员函数中使用。全局函数,静态函数都不能使用th

    2022年5月17日
  • 解决numpy.core._exceptions.UFuncTypeError: ufunc ‘add‘ did not contain a loop with signature matchin问题

    解决numpy.core._exceptions.UFuncTypeError: ufunc ‘add‘ did not contain a loop with signature matchin问题

    2021年7月13日
  • anaconda prompt系统找不到指定的路径_tensorflow怎么用

    anaconda prompt系统找不到指定的路径_tensorflow怎么用我们默认打开jupyternotebook一般是在C盘,那么久而久之你很多的代码都新建在C盘,以后想要清理的时候难免会比较困难,所以在这里推荐大家通过命令在D盘指定目录下打开jupyternotebook,那么你新建的所有文件都是在D盘的指定目录下啦!…

    2022年10月8日
  • linux 查看当前用户密码

    linux 查看当前用户密码用过Linux系统的人都知道,Linux系统查看用户不是会Windows那样,鼠标右键看我的电脑属性,然后看计算机用户和组即可。那么Linux操作系统里查看所有用户该怎么办呢?用命令。其实用命令就能很轻松的查看到Linux系统有哪些用户。  1、Linux里查看所有用户  (1)在终端里.其实只需要查看/etc/passwd文件就行了.  (2)看第三个参数:500以上的,就是后面建的用户了.其它则为系统的用户.  或者用cat/etc/passwd|cut-f1-d:  2、用.

    2022年6月4日
  • 如何使用python删除一个文件?

    如何使用python删除一个文件?若想利用python删除windows里的文件,这里需要使用os模块!那接下来就看看利用os模块是如何删除文件的!具体实现方法如下!os.remove(path)删除文件path.如果path是一个目录,抛出OSError错误。如果要删除目录,请使用rmdir().remove()同unlink()的功能是一样的在Windows系统中,删除一个正在使用的文件,将抛出异常。在…

    2022年5月13日

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号