做网站从哪方面入门,网站建设的维护工作,wordpress主题标签生成,西城网站建设浩森宇特一、项目简介 模仿小米的云服务#xff0c;实现一个通过TCP实现的私人云盘#xff0c;因为能力有限#xff0c;所以只实现自动云同步这一个功能#xff0c;具体可以分为三个小功能#xff0c;即保持云端和终端数据一致、实现文件的上传与下载以及手动同步
二、涉及到的知…一、项目简介 模仿小米的云服务实现一个通过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); //erronEINTR如果信号导致的中断重新执行一次 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,%saddrport\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 CCgcc CFLAGS-g -Wall server:server.c client:client.c MV_client: mv client /mnt/hgfs/Share/ clean:server client rm server client