当前位置: 首页 > 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…...

如何通过Odoo合同自动化与电子签名实现企业文档管理数字化转型

如何通过Odoo合同自动化与电子签名实现企业文档管理数字化转型 【免费下载链接】odoo Odoo. Open Source Apps To Grow Your Business. 项目地址: https://gitcode.com/GitHub_Trending/od/odoo 企业在合同管理过程中常面临效率低下、合规风险高、协作成本大等挑战。传统…...

线程与进程的区别与联系:操作系统入门详解(含 Python 示例)

、先搞懂&#xff1a;进程与线程到底是什么&#xff1f;&#xff08;通俗类比官方定义&#xff09; 1.1 生活化类比&#xff1a;快速建立认知 如果把计算机的操作系统比作一个大型工厂&#xff1a; 进程&#xff1a;就是工厂里的一个个独立车间。每个车间有自己专属的生产资…...

从Java转行大模型应用,Advanced-RAG 学习

一、RAG 进阶概述&#xff08;Advanced-RAG&#xff09;基础RAG&#xff08;检索增强生成&#xff09;核心是“检索生成”的两阶段流程&#xff0c;解决大模型“幻觉”和知识时效性问题&#xff0c;但在复杂场景&#xff08;长文档、模糊查询、高精准需求&#xff09;中存在检索…...

ChatGLM3-6B-128K在客服系统中的应用:智能回复生成

ChatGLM3-6B-128K在客服系统中的应用&#xff1a;智能回复生成 1. 引言 想象一下&#xff0c;一个繁忙的电商客服中心&#xff0c;每天要处理成千上万的客户咨询。传统的人工客服需要不断重复回答相似的问题&#xff0c;不仅效率低下&#xff0c;还容易因为疲劳而出错。现在&…...

开源串流新选择:用Sunshine打造跨设备游戏共享系统

开源串流新选择&#xff1a;用Sunshine打造跨设备游戏共享系统 【免费下载链接】Sunshine Sunshine: Sunshine是一个自托管的游戏流媒体服务器&#xff0c;支持通过Moonlight在各种设备上进行低延迟的游戏串流。 项目地址: https://gitcode.com/GitHub_Trending/su/Sunshine …...

从百兆到千兆:RJ45网口背后的技术演进与协议优化全解析

从百兆到千兆&#xff1a;RJ45网口背后的技术演进与协议优化全解析 当你拿起一根普通的网线连接电脑时&#xff0c;可能不会想到这根看似简单的线缆背后隐藏着怎样的技术革命。从最初的10Mbps到如今的千兆以太网&#xff0c;RJ45接口承载了网络通信技术的巨大飞跃。本文将带你深…...

自编码器在异常检测中的实战:如何用TensorFlow识别异常数据点

自编码器在异常检测中的实战&#xff1a;如何用TensorFlow识别异常数据点 金融交易中的一笔异常转账、工业设备传感器突然的读数波动、医疗影像中微小的病变区域——这些隐藏在庞大数据流中的异常信号&#xff0c;往往预示着关键风险或机会。传统基于阈值规则的检测方法在面对高…...

从‘下载失败弹个错’到‘优雅的用户体验’:前端文件下载错误处理与PDF预览的进阶实践

从‘下载失败弹个错’到‘优雅的用户体验’&#xff1a;前端文件下载错误处理与PDF预览的进阶实践 在当今的Web应用中&#xff0c;文件下载功能几乎是每个系统的标配。然而&#xff0c;很多开发者往往只关注功能的实现&#xff0c;而忽略了异常处理和用户体验的细节。当用户点…...

VSCode远程开发终极指南:5分钟搞定跳板机+服务器免密配置(附SSH密钥生成教程)

VSCode远程开发终极指南&#xff1a;5分钟搞定跳板机服务器免密配置 每次连接远程服务器都要输入密码、反复跳转终端&#xff0c;是不是已经让你精疲力尽&#xff1f;作为开发者&#xff0c;我们值得拥有更优雅的远程开发体验。今天要分享的这套方案&#xff0c;不仅能让你在VS…...

APKMirror客户端:安卓应用安全下载与管理的革新方案

APKMirror客户端&#xff1a;安卓应用安全下载与管理的革新方案 【免费下载链接】APKMirror 项目地址: https://gitcode.com/gh_mirrors/ap/APKMirror 在安卓应用获取的过程中&#xff0c;用户常常面临两难选择&#xff1a;官方应用商店的更新滞后与第三方平台的安全隐…...