美文网首页
C语言——通过网络对文件进行传输(简易网盘)

C语言——通过网络对文件进行传输(简易网盘)

作者: B_____b | 来源:发表于2019-04-03 14:34 被阅读0次

    通过之前三篇简书中介绍的 服务器客户端搭建 目录文件的复制 以及 变长数据包 可以完成一个简易的网盘功能。

    mkPDU sendPDU revPDU 及 PDU头文件 在<C语言——变长数据包>一文中有详解

    客户端上传:

    upload

    298 getStrFromSTDIN 是一个从终端抓取字符串的函数。

    301 lseek(文件描述符,偏移量,位置宏); 返回现在标记位置与文件头相差字节数

    off_t lseek(int fd, off_t offset, int whence);

    RETURN VALUE

          Upon successful completion, lseek() returns the resulting offset  loca‐

          tion  as  measured  in bytes from the beginning of the file.

    通过返回值 确定文件大小 然后生成对应大小的PDU

    304 g_uiId 全局变量 储存客户端id

    305 getFileName 的定义 

    通过查找路径字符串中的最后一个 \ 找到文件名

    void getFileName(char* path,char* name){

        char *p1 = path;

        char *p2 = NULL;

        int pos = 0;

        while(1){

            p2 = p1;

            p1 = strchr(p1+1,'/');

            if(NULL == p1){

                strcpy(name,p2);

                return ;

            }

        }

    }

    307 copyfileToPdu    //    将文件数据写入PDU

    void copyfileToPdu(const char* srcPath,PDU* pdu){

        int fdr = open(srcPath,O_RDONLY);

        if(-1 == fdr){

            printf("%s ",srcPath);

            perror("read file");

        }

        ssize_t ret = -1;

        ssize_t sended = 0;

        while(1){

            ret = read(fdr,(char*)(pdu->caMsg)+sended,4096);

            if(-1 == ret){

                if(EINTR == errno){

                    continue;

                }

                break;

            }else if(0 == ret){

            break;

            }

            sended+=ret;

        }

        close(fdr);

    }

    服务器处理上传请求:

    服务器端通过 pdu 中信息 首先根据 包中的用户信息 确定该用户的网盘存储路径

    之后将 pdu 中文件数据 存入该路径即可

    handleUpload

    300 g_pUsrLink 为一条储存信息的链表

    302 idToPath 将用户id转换为该用户网盘存储路径 之后和文件名拼接成最终文件存储路径

    这里id 为 整数

    void idToPath(uint id,char* path){

        char pathT[10] = {'\0'};

        int i = 0;

        int j = 0;

        while(1){

            j = id/10;

            for(int k=i;k>0;k--){

            pathT[k] = pathT[k-1];

            }

            pathT[0] = id- j*10 + '0';

            id = j;

            i++;

            if(id == 0){

                break;

            }

        }

        strcat(path,pathT);

    }

    305 copyFileFromPdu 与之前copyFileToPdu类似

    从pdu中将文件拷贝至对应地址

    void copyfileFromPdu(PDU* pdu,const char* desPath){

        int fdw = open(desPath,O_WRONLY|O_CREAT,0777);//默认权限全打开

        if(-1 == fdw){

            printf("%s ",desPath);

            perror("create file:");

            return;

        }

        ssize_t ret = -1;

        ssize_t left = pdu->uiMsgLen;

        ssize_t writed = 0;

    while(1){

        if(left <= 4096){

            write(fdw,pdu->caMsg+writed,left);

            break;

        }else{

            ret = write(fdw,pdu->caMsg+writed,4096);

            if(-1 == ret){

                if(EINTR == errno){

                continue;

                }

                break;

                }else if(0 == ret){

                    break;

                }

                left-=ret;

                writed+=ret;

            }

        }

        close(fdw);

    }

    下载:

    客户端向服务器发送下载请求的情况和 上传基本一致(因为懒) 这边就不重复了!

    相关文章

      网友评论

          本文标题:C语言——通过网络对文件进行传输(简易网盘)

          本文链接:https://www.haomeiwen.com/subject/nzgabqtx.html