项目_Linux_网络编程_私人云盘

概述

项目功能总述:

该项目使用TCP进行通信,实现文件的上传和下载。云盘的文件同步有手动同步、实时同步、定时同步这三种。本项目主要实现的是手动同步的功能,重点训练在如何使用TCP进行文件传输。

选择TCP的原因:

文件的传输需要可靠,因此选择TCP传输。

项目中需要解决的问题:

  • 文件如何上传和下载
  • 文件大小不确定如何处理
  • 文件个数不确定如何处理
  • 如何获取文件事件来实现实时同步
  • 如何使用定时器和守护进程来实现定时同步

传输文件时要解决的关键问题:

  • 如何处理文件路径,从而使得创建新文件的路径名正确
  • 如何处理TCP连包问题,封包拆包的自定义协议如何设定

编写Makefile

makefile编写整体思路:

该makefile的编写参考博文"8.Linux_Makefile" - "8、makefile编写技巧" - "8.3 分文件处理"。博文连接如下:8.Linux_Makefile-CSDN博客

文件创建: 

创建一个文件夹linux_test,在该文件夹下创建 "src、inc、obj目录"、"makefile文件"、"test.c文件"

在src文件中也创建一个 "makefile文件"

主目录下的makefile代码如下:

SRCDIR = $(shell pwd)/src
INCDIR = $(shell pwd)/inc
OBJDIR = $(shell pwd)/obj
SRC = $(wildcard $(SRCDIR)/*.c)
OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SRC)))
MAIN_SRCDIR = $(shell pwd)
SERVER_SRC = $(wildcard $(MAIN_SRCDIR)/server.c)
CLIENT_SRC = $(wildcard $(MAIN_SRCDIR)/client.c)
SERVER_OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(SERVER_SRC)))
CLIENT_OBJ = $(patsubst %.c,$(OBJDIR)/%.o,$(notdir $(CLIENT_SRC)))
CC = gcc
CFLAGS = -c -g -Wall -I $(INCDIR)
export OBJ OBJDIR CC CFLAGS all:debug $(SRCDIR) $(SERVER_OBJ) $(CLIENT_OBJ) server client
debug:
#	@echo "OBJDIR = $(OBJDIR)"
#	@echo "TEST_OBJ = $(TEST_OBJ)"
#调用其他makefile进行编译、汇编
$(SRCDIR):echo@make -C $@
echo:@echo "make start"
#编译、汇编server.c client.c 文件
$(SERVER_OBJ):server.c@$(CC) $(CFLAGS) $^ -o $@
$(CLIENT_OBJ):client.c@$(CC) $(CFLAGS) $^ -o $@
#链接全部.o生成可执行文件server client
server:$(OBJ) $(SERVER_OBJ)@$(CC) $^ -o server 
client:$(OBJ) $(CLIENT_OBJ)@$(CC) $^ -o client.PHONY:clean
clean:rm ./obj/*

src目录下的makefile代码如下:

all:debug $(OBJ)
debug:
#	@echo "OBJ = $(OBJ)"
#	@echo "OBJDIR = $(OBJDIR)"
$(OBJDIR)/%.o:%.c@$(CC) $(CFLAGS) $^ -o $@

TCP通信功能实现 

下面内容是以多进程并发形式编写服务端与客户端的代码,主要目的是实现通信的框架,使得双方可以进行通信。

 概述:

网络相关的代码封装在my_net.c、my_net.h中。

基本功能就是实现服务器与客户端可以相互通信。这里先使用单线程的方式进行框架的搭建。

具体实现逻辑见博文"13.1 Linux_网络编程_TCP/UDP" - "TCP" - "并发" - "多进程" 博文连接如下:

13.1 Linux_网络编程_TCP/UDP-CSDN博客

基本功能的my_net.h函数总览:

#ifndef __MY_NET_H
#define __MY_NET_H#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/wait.h>#define BACKLOG 5 	//最大接入客户端数量//TCP Server
int Socket_TcpServerInit(int argc,char** argv);
int Socket_TcpServerAccept(int fd);
//TCP Client
int Socket_TcpClientInit(int argc,char** argv);
//通用
ssize_t Socket_Read(int fd, void *buf, size_t count);
ssize_t Socket_Write(int fd, void *buf, size_t count);
//多进程并发
void Set_SIGCHLD(void);
void SIGCHLD_Handler(int sig);#endif

1、服务端

1、初始化socket服务器

该函数实现了创建IPv4的TCPsocket、地址快速复用、绑定端口号、监听客户端的功能。

/** socket_init: 初始化socket服务器* @param argc: main中的argc* @param argv: main中的argv* @ret 创建的socket文件描述符,如果失败会自动退出进程,该值不需要判断有效性* */
int Socket_TcpServerInit(int argc,char** argv){int fd;struct sockaddr_in addr;//参数有效性判断if(argc != 3){printf("param err\n");printf("%s<ip><port>\n",argv[0]);exit(-1);}printf("server ip = %s\n",argv[1]);printf("server port = %s\n",argv[2]);//1.创建socketif((fd=socket(AF_INET,SOCK_STREAM,0))<0){//IPv4,TCP协议perror("socket");exit(-1);}//地址快速重用int flag=1,len=sizeof(int);if(setsockopt(fd,SOL_SOCKET,SO_REUSEADDR,&flag,len) == -1){perror("setsockopt");exit(-1);}//2.绑定IP、端口号addr.sin_family = AF_INET;    				  //IPv4addr.sin_port = htons(atoi(argv[2])); 		  //端口号,要转化为大端子节序addr.sin_addr.s_addr = inet_addr(argv[1]);    //IP地址:0表示在本网络上的本主机,即:自己if(bind(fd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in)) == -1){perror("bind");exit(-1);}//3.监听socketif(listen(fd,BACKLOG) == -1){ 	//允许最多接入5个客户端perror("listen");exit(-1);}return fd;
}

 2、优化的accept函数

这个函数主要功能还是accept,但是封装了一些错误处理和接入客户端信息打印的操作。

/** Socket_TcpServerAccept: 优化的accept函数* @param fd: 服务器的socket文件描述符* @ret: 接入的客户端的socket文件描述符,如果失败会自动退出进程,该值不需要判断有效性* */
int Socket_TcpServerAccept(int fd){int newfd;struct sockaddr_in newAddr;socklen_t newAddrlen;do{//printf("Debug:again accept\n");newfd = accept(fd,(struct sockaddr*)&newAddr,&newAddrlen);}while(newfd < 0 && errno == EINTR);//如果是信号中断导致的错误,则重新执行acceptif(newfd < 0){perror("accept");exit(-1);}else{printf("[%s,%d]connect,fd=%d\n",inet_ntoa(newAddr.sin_addr),ntohs(newAddr.sin_port),newfd);}return newfd;
}

2、客户端

 1、初始化socket客户端

该函数实现了创建IPv4的TCPsocket、设置要连接服务器的信息、连接服务器的操作

/** Socket_TcpClientInit: 初始化socket客户端* @param argc: main中的argc* @param argv: main中的argv* @ret 创建的socket文件描述符,如果失败会自动退出进程,该值不需要判断有效性* */
int Socket_TcpClientInit(int argc,char** argv){int fd;struct sockaddr_in addr;//参数有效性判断if(argc != 3){printf("param err\n");printf("%s<ip><port>\n",argv[0]);exit(-1);}printf("connect server ip = %s\n",argv[1]);printf("connect server port = %s\n",argv[2]);//1.创建socketif((fd=socket(AF_INET,SOCK_STREAM,0))<0){//IPv4,TCP协议perror("socket");exit(-1);}//2.设置链接服务器的IP、端口号addr.sin_family = AF_INET;    				  //IPv4addr.sin_port = htons(atoi(argv[2])); 		  //端口号,要转化为大端子节序addr.sin_addr.s_addr = inet_addr(argv[1]);    //IP地址:0表示在本网络上的本主机,即:自己//3.链接服务器if(connect(fd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in)) == -1){perror("connect");exit(-1);}return fd;
}

3、通用读/写 

1、优化的read函数

该函数主要功能还是read,但封装了一些错误处理、读前清空缓冲区、自动回收退出的客户端资源的操作。

/** Socket_Read: 优化的read函数* @param: 参数含义与read一样* @ret: 返回值含义与read一样,如果失败会自动退出进程,该值不需要判断有效性* */
ssize_t Socket_Read(int fd, void *buf, size_t count){ssize_t	read_num;//读取数据do{//printf("Debug:again read\n");//清空缓冲区memset(buf,0,count);read_num = read(fd,buf,count);}while(read_num < 0 && errno == EINTR);//如果是信号中断导致的错误,则重新执行readif(read_num < 0){perror("read");exit(-1);}else if(read_num == 0){printf("Debug:read_num = 0,close fd=%d\n",fd);close(fd);}return read_num;
}

2、 优化的write函数

该函数主要功能还是write,但封装了一些错误处理、自动回收退出的客户端资源的操作。

/** Socket_Write: 优化的write函数* @param: 参数含义与write一样* @ret: 返回值含义与write一样,如果失败会自动退出进程,该值不需要判断有效性* */
ssize_t So

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/461733.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

[CUDA] atomic函数闭坑技巧

文章目录 1. 尽量减少atomic的使用频率2. 小心atomic的不规则读数 cuda atomic函数使用时的一些注意事项 1. 尽量减少atomic的使用频率 由于atomic会增加threads之间的同步性&#xff0c;所以在有选择性的atomic操作时&#xff0c;可以考虑用if(condition) atomic&#xff1b;…

开源全站第一个nextron项目--NextTalk:一款集成chatgpt的实时聊天工具

NextTalk 简介 该项目是一个基于Nextron(NextJSElectron)的桌面端实时聊天工具。 但由于使用了NextJS中的ssr及api route功能&#xff0c;该程序只能在开发环境运行。 关于生产版本&#xff1a;我将其网页端部分分离&#xff0c;并用Pake将其打包成桌面端&#xff0c;生产体…

河南高校大数据实验室建设案例分享

泰迪智能科技在与中国各地高校的合作中积累了丰富的经验&#xff0c;尤其是在大数据和人工智能领域。过去多年里与河南省内多所高校在大数据领域进行了积极的探索和建设&#xff0c;形成了一系列具有特色的大数据实验室。这些实验室不仅促进了高校内部的科研创新&#xff0c;也…

Kafka自动生产消息软件

点击下载《Kafka服务端(含Zookeeper)一键自启软件》 点击下载《kafka客户端生产者消费者kafka可视化工具&#xff08;可生产和消费消息&#xff09;》 点击下载《Kafka自动生产消息软件》 1. 前言 在软件开发过程中&#xff0c;Kafka常被用作消息队列来处理特定的业务功能。为…

龙迅#LT8668EX显示器图像处理芯片 适用于HDMI1.4+VGA转4PORT LVDS,支持4K30HZ分辨率,可做OSD菜单亮度调节!

1. 一般说明 LT8668EX 是 Lontium 的第二代 LCD 控制器&#xff0c;基于 ClearEdge 技术&#xff0c;支持 VGA 接口和 HDMI 接口&#xff0c;符合 HDMI 1.4 规范。它可以支持带 HDMI 接口的双模 DP。为了向后兼容&#xff0c;该 LCD 控制器还包括一个高性能模拟接口&#xff0…

分享SRC漏洞挖掘中js未授权漏洞挖掘的小技巧

文章目录 0x1 前言0x2 js未授权简介一、什么是未授权&#xff1f;二、常见的未授权访问漏洞三、js漏洞挖掘需要获取的几个信息四、如何挖掘五、浅谈 0x3浅谈 js未授权挖掘技巧一、常规js未授权挖掘二、浅谈交流 0x4 Findsomething应该怎样正确使用?问题一&#xff1a;findsome…

如何保护网站安全

1. 使用 Web 应用防火墙&#xff08;WAF&#xff09; 功能&#xff1a;WAF 可以实时检测和阻止 SQL 注入、跨站脚本&#xff08;XSS&#xff09;、文件包含等常见攻击。它通过分析 HTTP 流量来过滤恶意请求。 推荐&#xff1a;可以使用像 雷池社区版这样的 WAF&#xff0c;它提…

内感受性注意的电生理特征:频谱和源定位分析

摘要 对内感受信号的关注和有意识地处理能力被认为对最小自我、适应性自我调节和情感体验的发展&#xff0c;以及工具性和执行性认知功能的最佳表现至关重要。然而&#xff0c;尽管关于内感受推论解释的理论非常丰富&#xff0c;但实证证据仍然很少。在此基础上&#xff0c;本…

[OPEN SQL] FOR ALL ENTRIES IN

FOR ALL ENTRIES IN 语句用于从一个内部表中检索与另一个内部表中指定字段匹配的记录 语法格式 SELECT ... FOR ALL ENTRIES IN <itab> WHERE <cond>. <itab>&#xff1a;插入目标数据内表 <cond>&#xff1a;查询条件 使用FOR ALL ENTRY IN 语句时&…

GetX的一些高级API

目录 前言 一、一些常用的API 二、局部状态组件 1.可选的全局设置和手动配置 2.局部状态组件 1.ValueBuilder 1.特点 2.基本用法 2.ObxValue 1.特点 2.基本用法 前言 这篇文章主要讲解GetX的一些高级API和一些有用的小组件。 一、一些常用的API GetX提供了一些高级…

Windows下基于fping进行批量IP测试

fping是Linux下一个很好用的IP测试工具&#xff0c;结合代码可以完成批量的IP测试&#xff0c;在网络调试中用途很广。本文是基于fping for Windows结合bat批处理&#xff0c;定制的测试脚本样例。 一、程序信息 本次测试使用fpingV5.1 for Windows版&#xff0c;版本信息如下…

[MRCTF2020]你传你呢

[MRCTF2020]你传你&#x1f40e;呢 审题 一眼文件上传 知识点 .htaccess文件的作用 <FilesMatch "a.png"> SetHandler application/x-httpd-php </FilesMatch>将a.png当做php文件执行 AddType application/x-httpd-php .jpgAddType 是一个 Apach…

stm32cubeIde 使用笔记

划分flash空间 需要更改STM32xxx_FLASH.ld文件 输出其他格式文件

【Rust中的序列化:Serde(一)】

Rust中的序列化&#xff1a;Serde Serde是什么&#xff1f;什么是序列化序列化&#xff1f;Serde运行机制Serde Data ModelVistor ApiSerializer ApiDeserializer Api 具体示例流程分析具体步骤&#xff1a;那么依次这个结论是如何得出的呢?什么是de? 总结 Serde是什么&#…

【Flask】四、flask连接并操作数据库

目录 前言 一、 安装必要的库 二、配置数据库连接 三、定义模型 四、操作数据库 1.添加用户 2.删除用户 3.更新用户信息 4查询所有用户 五、测试结果 前言 在Flask框架中&#xff0c;数据库的操作是一个核心功能&#xff0c;它允许开发者与后端数据库进行交互&#xf…

手机实时提取SIM卡打电话的信令声音-新的篇章(三、Android虚拟声卡探索)

手机实时提取SIM卡打电话的信令声音-新的篇章(三、Android虚拟声卡探索) 前言 前面的篇章中&#xff0c;我们从理论方向和实际市面上出现的音频线传输声音的方式&#xff0c;讨论绕开手机对SIM卡电话通话声音的封锁场景的可行性&#xff0c;并实际选购几款数字和模拟的USB转接…

安装fpm,解决*.deb=> *.rpm

要从生成 .deb 包转换为 .rpm 包&#xff0c;可以按照以下步骤修改打包脚本 1. 使用 fpm 工具 fpm 是一个强大的跨平台打包工具&#xff0c;可以将 .deb 包重新打包成 .rpm&#xff0c;也可以直接从源文件打包成 .rpm。 安装 fpm sudo apt-get install ruby-dev sudo gem in…

青出于“蓝”的合资第一新能源,“换壳”背后有门道

文/王俣祺 导语&#xff1a;千呼万唤始出来的新能源“马6”终于亮相了&#xff0c;这款马自达EZ-6本以为凭借马自达多年来在国内市场深耕的底蕴可以收获一片支持&#xff0c;但最近却深陷“换壳”风波。那么今天我们就一起看看&#xff0c;这款马自达EZ-6和被冠以“原型”的深蓝…

HT8787B 可任意限幅、内置自适应升压的2x9.0W立体声音频功放

1 特性 ● 可任意配置的限幅功能 自由配置音频限制幅度&#xff0c;使输出音频信号限制在固定失真水平内 ● 内置自动限温控制功能 适应不同散热条件&#xff0c;避免出现过温关断现象 ● 高效自适应G类升压功能&#xff0c;有效延长播放时间 可调节最大限流值&#xff0c;有效…