当前位置: 首页 > news >正文

私人云盘(自动云同步)

一、项目简介

        模仿小米的云服务,实现一个通过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

相关文章:

私人云盘(自动云同步)

一、项目简介 模仿小米的云服务&#xff0c;实现一个通过TCP实现的私人云盘&#xff0c;因为能力有限&#xff0c;所以只实现自动云同步这一个功能&#xff0c;具体可以分为三个小功能&#xff0c;即保持云端和终端数据一致、实现文件的上传与下载以及手动同步 二、涉及到的知…...

【CMake】Linux 下权限丢失与软链接失效问题

【CMake】Linux 下权限丢失与软链接失效问题 文章目录 【CMake】Linux 下权限丢失与软链接失效问题问题概述解决方法1 - 安装目录2 - 安装文件3 - 手动指定 使用 Linux 下原生命令行注意事项参考链接 问题概述 一般使用 CMake 安装&#xff0c;在 Windows 平台不会出问题&…...

内部类介绍

内部类&#xff08;Inner Class&#xff09;是在另一个类的内部定义的类。它可以访问外部类的所有成员&#xff0c;包括私有成员。内部类有两种主要形式&#xff1a;局部内部类&#xff08;定义在方法内部&#xff09;和成员内部类&#xff08;定义在类的内部&#xff0c;但不在…...

【CVPR2021】LoFTR:基于Transformers的无探测器的局部特征匹配方法

LoFTR&#xff1a;基于Transformers的局部检测器 0. 摘要 我们提出了一种新的局部图像特征匹配方法。我们建议先在粗略级别建立像素级密集匹配&#xff0c;然后再在精细级别细化良好匹配&#xff0c;而不是按顺序进行图像特征检测、描述和匹配。与使用成本体积搜索对应关系的密…...

总结一下 C# 如何自定义特性 Attribute 并进行应用

前言 Attribute&#xff08;特性&#xff09;是一种用于为程序元素&#xff08;如类、方法、属性等&#xff09;提供元数据信息的方法。 特性是一种声明式的信息&#xff0c;附加到程序元素上&#xff0c;提供额外的数据用于描述和控制这些元素的行为。 在编译和运行时&…...

三种暴露方法和引入方式

1.分别暴露 export ...export...用于按需导出一个或多个模块&#xff0c;在导入时需要使用花括号指定导入的模块名称&#xff0c;例如import { a, b } from module module.js中 export let a 1 export function b(){console.log(hello,vue) } 2.统一暴露 export { ...}用于统…...

“Git之道:掌握常用命令,轻松管理代码“

目录 1. 初始化和配置 2. 提交和更新 3. 分支和合并 4. 查看和比较 5. 远程仓库 6. 文件操作命令 1. 初始化和配置 git init&#xff1a;在当前目录初始化一个新的Git仓库git config&#xff1a;配置Git的全局或局部选项git clone&#xff1a;从远程仓库克隆一个本地副本…...

Linux vim 文本编辑 操作文本 三种模式

介绍 vi 是一个经典的行编辑器&#xff0c;支持模式编辑&#xff08;包括普通模式、插入模式和命令模式&#xff09;。 vim 保留vi核心功能的基础上&#xff0c;增加了多级撤销、语法高亮、插件支持等高级功能。 两者的最大区别&#xff0c;简单的来说vim就是vi的增强版 三…...

JavaFX DatePicker

JavaFX DatePicker允许从给定日历中选择一天。DatePicker控件包含一个带有日期字段和日期选择器的组合框。JavaFX DatePicker控件使用JDK8日期时间API。 import javafx.application.Application; import javafx.scene.Scene; import javafx.scene.control.DatePicker; import j…...

开展“安全生产月”活动向媒体投稿的好方法找到了

作为一名单位的信息宣传员,我的职责是确保每一次重要活动的声音都能准确无误地传达到社会的每一个角落。在这样的使命驱动下,我曾一度陷入了一种传统的投稿模式——依赖电子邮件,将精心准备的稿件一封封地发送给各大媒体。初入此行,我满心以为这便是信息传播的路径,却未料到,这…...

商讯杂志商讯杂志社商讯编辑部2024年第10期目录

案例分享 基于胜任素质的干部选拔和梯队建设体系探讨——以A区卫生健康系统为例 康文雁; 1-4 “家庭五险一金”对居民商业保险购买存在挤出效应——基于江苏省徐州、淮安、泰州三市的实证研究 李炳毅; 5-8 人口老龄化背景下促进徐州市经济高质量发展的探究 李艳秋;…...

在VS Code中快速生成Vue模板的技巧

配置vue.json: { "Print to console": {"prefix": "vue","body": ["<template>"," <div class\"\">\n"," </div>","</template>\n","<scri…...

新火种AI|Sora发布半年之后,AI视频生成领域风云再起

作者&#xff1a;一号 编辑&#xff1a;美美 AI视频最近有些疯狂&#xff0c;Sora可能要着急了。 自OpenAI的Sora发布以来&#xff0c;AI视频生成技术便成为了科技界的热门话题。尽管Sora以其卓越的性能赢得了广泛关注&#xff0c;但其迟迟未能面向公众开放&#xff0c;让人…...

《UNIX环境高级编程》第三版(电子工业出版社出品)——两年磨一剑的匠心译作

历时两年&#xff0c;《UNIX环境高级编程》的翻译工作终于落下帷幕。这一路走来&#xff0c;真可谓是如鱼饮水&#xff0c;冷暖自知。还记得最初看到招募译者消息的那一刻&#xff0c;内心的激动难以言表。我毫不犹豫地报名&#xff0c;而后经历了试译、海选等激烈的角逐&#…...

【RK3588/算能/Nvidia智能盒子】AI“值守”,规范新能源汽车充电站停车、烟火及充电乱象

近年来&#xff0c;中国新能源汽车高速发展&#xff0c;产量连续8年位居全球第一。根据中国充电联盟数据&#xff0c;截至2023年6月&#xff0c;新能源汽车保有量1620万辆&#xff0c;全国充电基础设施累计数量为665.2万台&#xff0c;车桩比约2.5:1。 虽然新能源汽车与充电桩供…...

使用ReentrantLock和ThreadPoolExecutor模拟抢课

这里主要是在场景下帮助理解ReentrantLock和线程池的使用。 import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock;public class GrabCourseTask implements Runnable {private final String studentName;private static int availableS…...

VirtFuzz:一款基于VirtIO的Linux内核模糊测试工具

关于VirtFuzz VirtFuzz是一款功能强大的Linux内核模糊测试工具&#xff0c;该工具使用LibAFL构建&#xff0c;可以利用VirtIO向目标设备的内核子系统提供输入测试用例&#xff0c;广大研究人员可以使用该工具测试Linux内核的安全性。 工具要求 1、Rust&#xff1b; 2、修补的Q…...

统计学一(术语,正态)

目录 一&#xff0c;常用术语 二&#xff0c;正态分布&#xff08;Normal Distribution&#xff09; 三&#xff0c;中心极限定理(Central Limit Theorem) 一&#xff0c;常用术语 population(族群)&#xff1a;要统计的总的 populationSize(族群数量)&#xff1a;要统计的总…...

CleanMyMac X for Mac系统优化垃圾清理软件卸载 工具(小白轻松上手,简单易学)

Mac分享吧 文章目录 效果一、准备工作二、开始安装1、双击运行软件&#xff0c;将其从左侧拖入右侧文件夹中&#xff0c;等待安装完毕2、启动台显示软件图标&#xff0c;表示安装成功 三、运行测试1、打开软件&#xff0c;配置2、授权&#xff0c;允许完全磁盘访问 安装完成&a…...

从0开始开发一个简单web界面的学习笔记(HTML类)

文章目录 什么是HTML页面vscode 开放工具搭建第一个HTML页面编写vscode 如何快速生成代码框架html标签——注释、标题、段落、换行标签格式化标签img 标签(src 属性01)img 属性02(alt、title、width/height、border)a标签href属性a标签target属性表格标签01 基本属性表格标签02…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

eNSP-Cloud(实现本地电脑与eNSP内设备之间通信)

说明&#xff1a; 想象一下&#xff0c;你正在用eNSP搭建一个虚拟的网络世界&#xff0c;里面有虚拟的路由器、交换机、电脑&#xff08;PC&#xff09;等等。这些设备都在你的电脑里面“运行”&#xff0c;它们之间可以互相通信&#xff0c;就像一个封闭的小王国。 但是&#…...

Python爬虫实战:研究feedparser库相关技术

1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...

(二)原型模式

原型的功能是将一个已经存在的对象作为源目标,其余对象都是通过这个源目标创建。发挥复制的作用就是原型模式的核心思想。 一、源型模式的定义 原型模式是指第二次创建对象可以通过复制已经存在的原型对象来实现,忽略对象创建过程中的其它细节。 📌 核心特点: 避免重复初…...

【论文笔记】若干矿井粉尘检测算法概述

总的来说&#xff0c;传统机器学习、传统机器学习与深度学习的结合、LSTM等算法所需要的数据集来源于矿井传感器测量的粉尘浓度&#xff0c;通过建立回归模型来预测未来矿井的粉尘浓度。传统机器学习算法性能易受数据中极端值的影响。YOLO等计算机视觉算法所需要的数据集来源于…...

高危文件识别的常用算法:原理、应用与企业场景

高危文件识别的常用算法&#xff1a;原理、应用与企业场景 高危文件识别旨在检测可能导致安全威胁的文件&#xff0c;如包含恶意代码、敏感数据或欺诈内容的文档&#xff0c;在企业协同办公环境中&#xff08;如Teams、Google Workspace&#xff09;尤为重要。结合大模型技术&…...

LLM基础1_语言模型如何处理文本

基于GitHub项目&#xff1a;https://github.com/datawhalechina/llms-from-scratch-cn 工具介绍 tiktoken&#xff1a;OpenAI开发的专业"分词器" torch&#xff1a;Facebook开发的强力计算引擎&#xff0c;相当于超级计算器 理解词嵌入&#xff1a;给词语画"…...

拉力测试cuda pytorch 把 4070显卡拉满

import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试&#xff0c;通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小&#xff0c;增大可提高计算复杂度duration: 测试持续时间&#xff08;秒&…...

Java编程之桥接模式

定义 桥接模式&#xff08;Bridge Pattern&#xff09;属于结构型设计模式&#xff0c;它的核心意图是将抽象部分与实现部分分离&#xff0c;使它们可以独立地变化。这种模式通过组合关系来替代继承关系&#xff0c;从而降低了抽象和实现这两个可变维度之间的耦合度。 用例子…...

音视频——I2S 协议详解

I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议&#xff0c;专门用于在数字音频设备之间传输数字音频数据。它由飞利浦&#xff08;Philips&#xff09;公司开发&#xff0c;以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...