lv8 嵌入式开发 网络编程开发 21 私有云盘项目

目录

1云盘项目简介

2 项目实现

2.1 首先实现TCP客户端、服务端

2.2 实现客户端函数简化

2.3 实现服务端函数简化

2.4 TCP数据连包现象

2.5 封装send函数和recv函数

2.6 建立readme说明

2.7 实现文件传输

2.8 读取配置文件种的ip、端口号,通过argv[1]参数实现文件传输

3 最终项目 


1云盘项目简介

常见的云盘服务软件

lv8 嵌入式开发 网络编程开发 21 私有云盘项目_第1张图片

什么是云同步? 

  • 保持云端数据和终端数据的一致
  • 上传和下载
  • 实时同步
  • 定时同步
  • 手动同步

需求分析

  • 文件的上传和下载
  • 文件的大小不确定(文件太大,upd传输就不合适)
  • 文件的个数不确定
  • 实时同步需要获取文件事件(因为用循环太占cpu)
  • 定时同步需要设置定时器
  • 使用TCP实现手动同步

如何实现手动同步?

  • 实现TCP通信
  • 使用TCP实现文件的上传和下载
  • 实现整个目录下的文件的同步
  • 实现项目框架
  • 完成项目

2 项目实现

2.1 首先实现TCP客户端、服务端

cloud-project_v1

为了方便管理头文件,新建tcp.h

#ifndef _TCP_H
#define _TPC_H

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define ErrExit(msg) do{ perror(msg); \              //异常处理宏定义
						 exit(EXIT_FAILURE);\
					   }while(0);
typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;
#define BACKLOG 5

#endif

实现server.c

#include "tcp.h"

int main(int argc, char *argv[])
{
	int ret, fd, newfd;
	Addr_in addr,client_addr;
	socklen_t addrlen = sizeof(client_addr);
	char buf[BUFSIZ] = {};


	//检查参数
	if(argc < 3)
	{
		fprintf(stderr, "%s  \n", argv[0]);
		exit(EXIT_FAILURE);
	}

	//创建套接字
	if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		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(bind(fd,(Addr *)&addr, sizeof(addr)))
		ErrExit("bind");

	//监听模式
	if(listen(fd, BACKLOG))
		ErrExit("listen");

	//接收客户端链接
	bzero(&client_addr,sizeof(client_addr));
	do
	{
		newfd = accept(fd, (Addr *)&client_addr, &addrlen);
	}while(newfd < 0 && errno == EINTR);
	if(newfd < 0)
		ErrExit("accept");

	//接收客户端数据
	while(1)
	{
		do 
		{
			ret = recv(newfd, buf, BUFSIZ, 0);
		}while(ret < 0 && errno == EINTR); //如果信号导致的错误,继续执行
		if(ret < 0)
		{
			ErrExit("recv");
		}
		else if(!ret)  //ret = 0 客户端退出
		{
			break;
		}
		else           //ret > 0
		{
			printf("[%s:%d]buf:%s\n", 
					inet_ntoa(client_addr.sin_addr), 
					ntohs(client_addr.sin_port), buf);
		}
	
	}

	close(newfd);
	close(fd);
	return 0;
}

实现服务端client.c(复制服务端进行改动)

#include "tcp.h"

int main(int argc, char *argv[])
{
	int ret, fd;
	Addr_in addr;
	char buf[BUFSIZ] = {"===test"};

	//检查参数
	if(argc < 3)
	{
		fprintf(stderr, "%s  \n", argv[0]);
		exit(EXIT_FAILURE);
	}

	//创建套接字
	if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		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(fd,(Addr *)&addr, sizeof(addr)))
		ErrExit("bind");

	//发送数据
	while(1)
	{
		do 
		{
			ret = send(fd, buf, BUFSIZ, 0);
		}while(ret < 0 && errno == EINTR); //如果信号导致的错误,继续执行
		if(ret < 0)
		{
			ErrExit("recv");
		}
		else if(!ret)  //ret = 0
		{
			break;
		}
		printf("send data:%s\n", buf);
        fflush(stdout);
		getchar();
	
	}

	close(fd);
	return 0;
}

最终实现效果,客户端发送,服务端打印===test

lv8 嵌入式开发 网络编程开发 21 私有云盘项目_第2张图片

2.2 实现客户端函数简化

cloud_project_v1.1客户端给服务端传文件

主要工作:

  • 封装客户端socket创建过程的函数,简化代码
  • 创建makefile

tcp.h

#ifndef _TCP_H_
#define _TCP_H_

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 

#define BACKLOG 5

#define ErrExit(msg) do { perror(msg); \
	exit(EXIT_FAILURE); } while(0)

typedef struct sockaddr Addr;
typedef struct sockaddr_in Addr_in;

void Argment(int argc, char *argv[]);
int SocketInit(char *argv[]);
#endif

tcp.c

#include "tcp.h"

void Argment(int argc, char *argv[]){
	if(argc < 3){
		fprintf(stderr, "%s \n", argv[0]);
		exit(EXIT_FAILURE);
	}
}

int SocketInit(char *argv[]){
	int fd;
	Addr_in addr;
	/*创建套接字*/
	if( (fd = socket(AF_INET, SOCK_STREAM, 0) ) < 0)
		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(fd, (Addr *)&addr, sizeof(addr) ) )
		ErrExit("connect");
	return fd;
}

 client.c

#include "tcp.h"

int main(int argc, char *argv[])
{
	int fd;
	int ret;
	char buf[BUFSIZ] = {"===test==="};
	/*检查参数*/
	Argment(argc, argv);

	fd = SocketInit(argv);

	/*发送数据*/
	while(1){
		do {
			ret = send(fd, buf, BUFSIZ, 0);
		}while(ret < 0 && errno == EINTR); //如果信号导致的错误,继续执行
		if(ret < 0)
			ErrExit("recv");
		else if(!ret)
			break;
		printf("send data:%s", buf);
		fflush(stdout);
		getchar();
	}

	close(fd);
	return 0;
}

server.c

#include "tcp.h"

int main(int argc, char *argv[])
{
	int ret, fd, newfd;
	Addr_in addr,client_addr;
	socklen_t addrlen = sizeof(client_addr);
	char buf[BUFSIZ] = {};


	//检查参数
	if(argc < 3)
	{
		fprintf(stderr, "%s  \n", argv[0]);
		exit(EXIT_FAILURE);
	}

	//创建套接字
	if((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
		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);
	}
	
	//绑定通

你可能感兴趣的:(嵌入式开发,网络,linux)