私人云盘(自动云同步)

2024-06-12 12:52
文章标签 自动 同步 私人 云盘

本文主要是介绍私人云盘(自动云同步),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、项目简介

        模仿小米的云服务,实现一个通过TCP实现的私人云盘,因为能力有限,所以只实现自动云同步这一个功能,具体可以分为三个小功能,即保持云端和终端数据一致、实现文件的上传与下载以及手动同步

二、涉及到的知识点

        主要有文件的打开与关闭,文件的发送与接收,文件的写入及socket通信,为了项目整体的间接性,还使用到的枚举类型的结构体以及链表

三、TCP通信实现流程图

四、讲解

在项目实现过程中,代码程序修改了多次,我将最终的项目程序压缩包上传到了我的资源上面,有兴趣的可以自行下载。

这里放的程序是我在编写项目程序过程中的一个版本,只实现了单个文件的传输,需要自己手动输入要传输的文件,最终的版本在资源里面请不要搞错了

1、文件说明:

        ①client.c       是客户端的代码

        ②server.c      是服务器端的代码

        ③tcp.c          是客户端和服务器所使用到的一些头文件,以及自己封装的一些函数和自定义的宏

        ④Makefile     这个就不用多说了吧

2、程序文件

client.c文件

#include "tcp.h"
#define FILENAME "森林风声-呜呼呜呼-树木摇曳.mp3"

int main(int argc,char *argv[]){
    int socketfd,filefd;
    int ret;
    char buf[BUFSIZ];
    /*检查参数*/
    Argment(argc,argv);
    /*创建套接字并对其初始化*/
    socketfd = SocketInit_Client(argv);
    /*打开文件*/
    filefd = open(FILENAME,O_RDONLY);
    if(filefd == -1){
        ErrExit("open");
    }
    /*发送文件名字*/
    SocketDataHandle(socketfd,FILENAME,strlen(FILENAME),(DataHand_t)send);
    SocketDataHandle(socketfd,buf,1,recv);
    /*发送文件内容*/
    if(buf[0] == OK){
        while(1){
            do{
                ret = read(filefd,buf,BUFSIZ);
            }while(ret < 0 && errno == EINTR);
        if(ret < 0){
            ErrExit("read");
        }
        if(!ret){
            break;
        }
        ret = SocketDataHandle(socketfd,buf,ret,(DataHand_t)send);
        if(!ret){
            break;
        }
        }
    }
    close(filefd);
    close(socketfd);
    return 0;
}


server.c文件

#include "tcp.h"

int main(int argc,char *argv[]){
    int socketfd,newsocketfd,filefd;
    int ret;
    char buf[BUFSIZ] = {};
    Addr_in clientaddr;
    socklen_t addrlen = sizeof(Addr_in);
    /*检查参数*/
    Argment(argc,argv);
    /*创建套接字*/
    socketfd = SocketInit_server(argv);
    /*接收客户端的连接并生成一个新的套接字*/
    do{
        newsocketfd = accept(socketfd,(Addr *)&clientaddr,&addrlen);
     }while(newsocketfd < 0 && errno == EINTR);  //erron=EINTR如果信号导致的中断,重新执行一次
    if(newsocketfd == -1){
        ErrExit("accept");
    }
    /*接收文件名字*/
    ret = SocketDataHandle(newsocketfd,buf,BUFSIZ,recv);
    /*创建文件*/
    filefd = open(buf,O_WRONLY|O_CREAT,0660);
    if(filefd == -1){
        ErrExit("open");
    }
    buf[0] = OK;
    SocketDataHandle(newsocketfd,buf,1,(DataHand_t)send);
    /*接收文件*/
    while(1){
        ret = SocketDataHandle(newsocketfd,buf,BUFSIZ,recv);
        if(!ret){
            break;
        }
        write(filefd,buf,ret);
    }
    close(filefd);
    close(newsocketfd);
    close(socketfd);
    return 0;
}
 

tcp.h文件

#ifndef _TCP_H_
#define _TCP_H_

/*使用的头文件*/
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <errno.h>
#include <math.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <netinet/tcp.h>

/*自己定义的宏*/
#define ErrExit(msg) do{perror(msg); exit(EXIT_FAILURE);}while(0)
#define BACKLOG 5
#define OK '1'
typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;
typedef ssize_t(* DataHand_t)(int ,void *,size_t,int);

/*函数声明*/
void Argment(int argc,char *argv[]);
int SocketInit_Client(char *argv[]);
int SocketInit_server(char *argv[]);
int SocketDataHandle(int fd,void *buf,size_t len,DataHand_t datahandle);

//参数检查函数
void Argment(int argc,char *argv[]){
    if(argc < 3){
        fprintf(stdin,"%s<addr><port>\n",argv[0]);
        exit(EXIT_FAILURE);
    }
}

//初始化客户端套接字函数
int SocketInit_Client(char *argv[]){
    int socketfd;
    Addr_in addr;
    /*创建套接字*/
    socketfd = socket(AF_INET,SOCK_STREAM,0);
    if(socketfd == -1){
        ErrExit("socket");
    }
    /*设置通信结构体*/
    bzero(&addr,sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    if(inet_aton(argv[1],&addr.sin_addr) == 0){
        fprintf(stderr,"Invalid address\n");
        exit(EXIT_FAILURE);
    }
    /*发起连接请求*/
    if(connect(socketfd,(Addr *)&addr,sizeof(addr)) == -1){
        ErrExit("connect");
    }
    return socketfd;
}

//初始化服务器端套接字函数
int SocketInit_server(char *argv[]){
    int socketfd;
    Addr_in addr;
    /*创建套接字*/
    socketfd = socket(AF_INET,SOCK_STREAM,0);
    if(socketfd == -1){
        ErrExit("socket");
    }
    /*设置地址快速重用*/
    int flag = 1;
    if(setsockopt(socketfd,SOL_SOCKET,SO_REUSEADDR,&flag,sizeof(flag)) == -1){
        perror("setsockopt");
    }
    /*设置通信结构体*/
    bzero(&addr,sizeof(addr));
    addr.sin_family = AF_INET;
    addr.sin_port = htons(atoi(argv[2]));
    if(inet_aton(argv[1],&(addr.sin_addr)) == 0){
        fprintf(stderr,"Invalid address\n");
        exit(EXIT_FAILURE);
    }
    /*绑定通信结构体*/
    if(bind(socketfd,(Addr *)&addr,sizeof(addr)) == -1){
        ErrExit("bind");
    }
    /*设置套接字的模式为监听*/
    if(listen(socketfd,BACKLOG) == -1){
        ErrExit("listen");
    }
    return socketfd;
}

//数据处理函数
int SocketDataHandle(int fd,void *buf,size_t len,DataHand_t datahandle){
    int ret;
    char *str = datahandle == recv?"recv":"send";
    do{
        ret = datahandle(fd,buf,len,0);
    }while(ret < 0 && errno == EINTR);
    if(ret < 0){
        ErrExit(str);
    }
    return ret;
}

#endif

Makefile文件


all:server client
CC=gcc
CFLAGS=-g -Wall

server:server.c
client:client.c

MV_client:
    mv client /mnt/hgfs/Share/

clean:server client
    rm server client

这篇关于私人云盘(自动云同步)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1054276

相关文章

时间服务器中,适用于国内的 NTP 服务器地址,可用于时间同步或 Android 加速 GPS 定位

NTP 是什么?   NTP 是网络时间协议(Network Time Protocol),它用来同步网络设备【如计算机、手机】的时间的协议。 NTP 实现什么目的?   目的很简单,就是为了提供准确时间。因为我们的手表、设备等,经常会时间跑着跑着就有误差,或快或慢的少几秒,时间长了甚至误差过分钟。 NTP 服务器列表 最常见、熟知的就是 www.pool.ntp.org/zo

WordPress网创自动采集并发布插件

网创教程:WordPress插件网创自动采集并发布 阅读更新:随机添加文章的阅读数量,购买数量,喜欢数量。 使用插件注意事项 如果遇到404错误,请先检查并调整网站的伪静态设置,这是最常见的问题。需要定制化服务,请随时联系我。 本次更新内容 我们进行了多项更新和优化,主要包括: 界面设置:用户现在可以更便捷地设置文章分类和发布金额。代码优化:改进了采集和发布代码,提高了插件的稳定

【青龙面板辅助】JD商品自动给好评获取京豆脚本

1.打开链接 开下面的链接进入待评价商品页面 https://club.jd.com/myJdcomments/myJdcomments.action?sort=0 2.登陆后执行脚本 登陆后,按F12键,选择console,复制粘贴以下代码,先运行脚本1,再运行脚本2 脚本1代码 可以自行修改评价内容。 var content = '材质很好,质量也不错,到货也很快物流满分,包装快递满

AI炒股:自动画出A股股票的K线图并添加技术指标

在deepseek中输入提示词: 你是一个Python编程专家,要完成一个编写Python脚本的任务,具体步骤如下: 用AKShare库获取股票贵州茅台(股票代码:600519)在2024年3月7日到2024年6月5日期间的历史行情数据-前复权。 然后绘制K线图,并在K线图上添加布林线、MACD 注意: 每一步都要输出信息到屏幕上; 日期格式是YYYYMMDD; 设置中文字体,以解决

XMG 自动提示宏 #define keyPath(objc,keyPath) @(((void)objc.keyPath,#keyPath));

1. int a=((void)5,4)  C语言逗号表达式默认会取右边的内容 如果不写void的话 a会被报警告,写上void标明请忽略左边的内容 插曲刚才弄得,已经上线的苹果产品如果需要下架的话,点击 价格与销售范围,然后点击下架。这个产品就会在AppStore 中移除。如果想再让改产品重新在Apple store中显示,那么再次让他上线就可以了。但是会有一定的时间延迟 /

自动驾驶---Perception之Lidar点云3D检测

1 背景         Lidar点云技术的出现是基于摄影测量技术的发展、计算机及高新技术的推动以及全球定位系统和惯性导航系统的发展,使得通过激光束获取高精度的三维数据成为可能。随着技术的不断进步和应用领域的拓展,Lidar点云技术将在测绘、遥感、环境监测、机器人等领域发挥越来越重要的作用。         目前全球范围内纯视觉方案的车企主要包括特斯拉和集越,在达到同等性能的前提下,纯视觉方

Linux-笔记 线程同步机制

目录 前言 实现 信号量(Semaphore) 计数型信号量 二值信号量  信号量的原语操作 无名信号量的操作函数 例子 互斥锁(mutex) 互斥锁的操作函数 例子 自旋锁 (Spinlock) 自旋锁与互斥锁的区别 自旋锁的操作函数 例子 前言         线程同步是为了对共享资源的访问进行保护,确保数据的一致性,由于进程中会有多个线程的存在,

java同步锁以及级别升级的理解

首先简单说下先偏向锁、轻量级锁、重量级锁三者各自的应用场景: 偏向锁:只有一个线程进入临界区;轻量级锁:多个线程交替进入临界区;重量级锁:多个线程同时进入临界区。 还要明确的是,偏向锁、轻量级锁都是JVM引入的锁优化手段,目的是降低线程同步的开销。比如以下的同步代码块:   synchronized (lockObject) { // do something } 上述同步代码块

Linux开机自动启动ORACLE设置

Redhat init简介: Linux启动时,会运行一个init程序,然后由init来启动后面的任务,包括多用户环境(inittab中设定)和网络等。运行级就是当前程序运行的功能级别,这个级别从1到6,具有不同的功能。这些级别在/etc/inittab(其他发行版这个文件位置不同)中指定,该文件就是init程序寻找的主要文件。最先运行的服务放在/etc/rc.d目录下。

自动驾驶规划中使用 OSQP 进行二次规划 代码原理详细解读

目录 1 问题描述 什么是稀疏矩阵 CSC 形式 QP Path Planning 问题 1. Cost function 1.1 The first term: 1.2 The second term: 1.3 The thrid term: 1.4 The forth term: 对 Qx''' 矩阵公式的验证 整体 Q 矩阵(就是 P 矩阵,二次项的权重矩阵)