Llinux微型文件传输_第1页
Llinux微型文件传输_第2页
Llinux微型文件传输_第3页
Llinux微型文件传输_第4页
Llinux微型文件传输_第5页
已阅读5页,还剩20页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、局域网文件传输系统项目说明需求说明:1,开发平台1.1 linux x86 641.2 支持Debian Ubuntu1.3 支持rhel,centos,Fedora2,功能说明1.1 文件上传与下载,讲指定文件上传到服务器,抑从服务器下载文件到指定位置1.2 文件浏览,浏览本地文件以及服务器端文件1.3 概要功能说明1.3.1 客户端主要任务:1) 分析用户输入的命令2) 根据命令向服务器端发出请求3) 等待服务器返回的结果 表1_1 命令含义与请求码用户输入的命令命令含义对应的请求码Get从服务器得到文件GETPut向服务器传输文件PUTCd进入客户端的目录不需要与服务端通信,因此无请求!

2、cd进入服务器端目录CDLs列出客户端当前的内容不需要与服务端通信因此无请求!ls列出服务器端当前的内容LSConnect连接服务器发出连接请求,不需要服务器额外处理Bye退出程序BYE 表1_2 命令的格式命令的名称格式说明getget arg1 arg2。 arg1:源文件 arg2:本地路径。 arg1,arg2都是绝对路径putput arg1 arg1。arg1:本地文件 arg1:目标路径。 arg1 arg2都是绝对路径!cd!cd arg1。 arg1:指定的服务器目录。绝对路径!ls!ls arg1。 arg1:指定的目录。绝对路径connect connect arg1。

3、arg1:点分十进制IP地址cdcd arg1。 arg1:客户端的指定目录,绝对路径lsls arg1。 arg1:客户端指定目录,绝对路径byebye。1.3.2 服务器端主要任务1) 分析请求代码2) 根据请求代码做相应的处理3) 等待返回结果或者应答信息表1_3请求码与相应处理请求代码对应的处理GET向客户端传输文件PUT接受客户端的文件CD进入目录LS将当前目录内容传输给客户端BYE断开连接通信协议与服务器模型:本项目通信协议分两种对于get命令和!ls命令这些需要传输文件内容的命令(!ls需要传输列出的目录文件列表),采用四次握手的通信协议如图1_1所示ServerClientSe

4、rverServerServerClientClientClient客户端命令应答信息RDY信息传输的文件内容 图1_1 四次握手通信协议以get命令举例,get命令首先发出get请求,服务器程序接收到请求后,发送请求的文件长度或者错误应答码,接收到文件长度后客户端发送RDY应答信息,服务器端开始传输文件内容对于!CD命令这种不需要传输文件内容的命令采取两次握手通信协议,如图1_2所示ServerServerClientClient客户端命令命令执行是否成功 图1_2 两次握手通信协议 本项目服务器采用多线程并发服务器模型,提供和客户端的交互。 3,源代码目录结构 Svr common.h 总

5、领整个服务器程序的头文件 command.h 定义命令处理函数和初始化函数头文件 command.c 定义命令处理函数和初始化函数 main.c 定义程序主干函数 makefile Cli common.h 总领整个服务器程序的头文件,常用通文件皆放与此 command.h 定义命令处理函数和初始化函数头文件 command.c 定义命令处理函数和初始化函数 main.c 客户端主干函数. input.c 定义命令分解函数,用于处理用户输入的命令 makefile4,核心函数及数据结构定义 4.1 客户端 int do_connect(char *ip, int *sock_fd); 与服务器

6、端进行连接 int do_get(const char *src, const char *dst, int sock_fd);从远端服务器下载文件 int do_put(const char *src, const char *dst, int sock_fd);向远端服务器上传文件 int do_cd(char *path);进入当前主机指定目录 int do_ls(char *path); 列出当前主机指定目录下的内容 int do_serv_cd(char *path, int sock_fd);进入远端服务器指定目录 int do_serv_ls(char *path, int so

7、ck_fd);列出当前服务器目录信息 int bye(int sock_fd);退出服务器,关闭连接 int split(struct commamd_line, char line);拆分命令相关函数struct command_line char *name; 命令的名称 char *argvMAX_ARG; 命令携带的参数 ;MAX_LINE 1024 向服务器端发送命令的最大长度PORT 8000 端口号COMMAND_LINE 256 用户输入客户端命令的最大长度MAX_LENGTH 64 每个参数或命令的最大长度 4.2 服务器 int do_get(const char *src

8、, const char *dst, int sock_fd); 处理用户的put命令 int do_put(const char *src, const char *dst, int sock_fd); 处理用户的get命令 int do_cd(char *path); 处理用户的!cd请求 int do_ls(char *path); 处理用户的!ls请求ADDR_LEN 17 点分十进制IP地址的长度,包括最后的结束符5,客户端执行流程 5.1 输出提示信息 5.2 接受用户输入的命令 5.3 输入命令是否为空,为空则程序正常退出,非空则继续 5.4 输入命令是否为bye,是则程序正常退

9、出,否则继续 5.5 处理用户输入的命令 5.6 输出提示信息,继续循环执行5.15.5的过程6,服务器执行流程 6.1 服务器启动 6.2 是否接收到一个连接,是则继续,否则等待 6.3 创建连接是否成功,是则继续,否则打印出错信息 6.4 创建一个子线程,是则继续,否则打印出错信息 6.5 接收客户端传输的命令 6.6 解析命令 6.7 重复6.26.6过程部分测试命令(取决于你放文件的位置,仅供参考):put /home/ubuntu/Linux_Ser_Cli/Client/text/a.txt /home/ubuntu/Linux_Ser_Cli/Server/textput /ho

10、me/ubuntu/Linux_Ser_Cli/Client/text/user.txt /home/ubuntu/Linux_Ser_Cli/Server/textget /home/ubuntu/Linux_Ser_Cli/Server/text/b.txt /home/ubuntu/Linux_Ser_Cli/Client/text源文件:客户端:/Client common.h#pragma once#include <stdio.h>#include <stdlib.h>#include "command.h"/Client command

11、.h#pragma once#include "common.h"#include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <dirent.h>#include <unistd.h>#include <errno.h>#include <limits.h>#define MAX_LINE 1024 /

12、向服务器端发送命令的最大长度#define PORT 8000 /端口号#define COMMAND_LINE 256 /用户输入客户端命令的最大长度#define MAX_LENGTH 64 /每个参数或命令的最大长度#define MAX_ARG 4struct command_line char *name; / 命令的名称 char *argvMAX_ARG; /命令携带的参数 ;int do_connect(char *ip, int *sock_fd); /与服务器端进行连接int do_get(const char *src, const char *dst, int sock

13、_fd);/从远端服务器下载文件int do_put(const char *src, const char *dst, int sock_fd);/向远端服务器上传文件int do_cd(char *path); /进入当前主机指定目录int do_ls(char *path); /列出当前主机指定目录下的内容int do_serv_cd(char *path, int sock_fd); /进入远端服务器指定目录int do_serv_ls(char *path, int sock_fd); /列出当前服务器目录信息int bye(int sock_fd); /退出服务器,关闭连接int

14、split(struct command_line *com, char line); /拆分命令相关函数char * path_alloc(size_t *sizep); /获取存放完整路径的内存空间起始地址和大小 int input();struct command_line comd;int sock_fd;int argv; /输入的参数个数/Client command.c#include "common.h"int do_connect(char *ip, int *sock_fd) /与服务器端进行连接int res;socklen_t len;char bu

15、f100 = ""struct sockaddr_in svraddr,cliaddr;bzero(&cliaddr,sizeof(cliaddr); /把一段内存区的内容全部设置为0*sock_fd = socket(PF_INET,SOCK_STREAM,0);svraddr.sin_family = AF_INET;svraddr.sin_port = htons(1234);inet_pton(AF_INET,ip,&(svraddr.sin_addr);res = connect(*sock_fd,(struct sockaddr*)(&s

16、vraddr),sizeof(svraddr);read(*sock_fd,buf,sizeof(buf);printf("%sn",buf); /printf("Connet Server Scuess!n")return res;int do_cd(char *path) /进入当前主机指定目录 char *ptr; / 记录改变后的文件目录 size_t size; if(chdir(path) < 0) perror("chdir failed!n"); ptr = path_alloc(&size); /our

17、 own function if(getcwd(ptr,size) = NULL) perror("getcwd failed!n"); printf("cwd = %sn",ptr); return 0;int do_ls(char *path) /列出当前主机指定目录下的内容DIR *dp;struct dirent *dirp;if(dp = opendir(path) = NULL)printf("cant open %sn",path);while(dirp = readdir(dp) != NULL)printf(&quo

18、t;%sn",dirp->d_name);closedir(dp);return 0;int do_put(const char *src, const char *dst, int sock_fd) /向远端服务器上传文件FILE * fp;char b_tMAX_LENGTH; /记录argv1的临时变量char bufferMAX_LINE;char file_nameMAX_LENGTH;int file_block_length = 0; /文件int i = 0.,j = 0,len = 0;int res = 0;if(sock_fd >= 0) print

19、f("Create Socket Sucess!n"); elseperror("Failed!n");exit(1);write(sock_fd,,sizeof();/向服务器发送操作符printf(":%sn",); bzero(buffer,sizeof(buffer);strcpy(buffer,src);send(sock_fd,buffer,sizeof(buffer),0);/send(sock_fd,src,sizeof(src),0);print

20、f("src:%sn",buffer);bzero(buffer,sizeof(buffer);strcpy(buffer,dst);send(sock_fd,buffer,sizeof(buffer),0);printf("dst:%sn",buffer);recv(sock_fd,buffer,sizeof(buffer),0);/Readyprintf("buffer:%sn",buffer);if(strcmp(buffer,"Ready") = 0)bzero(buffer,sizeof(buffer);

21、strcpy(b_t,src);len = strlen(b_t);i = len - 1;while(b_ti != '/') /*提取文件名*/i-;i+;while(i < len)file_namej+ = b_ti;i+;file_namej = '0' send(sock_fd,file_name,sizeof(file_name),0);printf("Send Server File Name:%sn",file_name);bzero(buffer,sizeof(buffer); recv(sock_fd,buffer

22、,sizeof(buffer),0); printf("Recv From Server:%sn",buffer);/OKbzero(buffer,sizeof(buffer); fp = fopen(src,"r"); if(NULL = fp ) printf("File:t%s Not Foundn", file_name); else bzero(buffer, sizeof(buffer); while( (file_block_length = fread(buffer,sizeof(char),MAX_LINE,fp)&

23、gt;0) printf("file_block_length = %dn",file_block_length);res = send(sock_fd,buffer,file_block_length+1,0); if(res<0) printf("Send File:t%s Failedn", file_name); break; bzero(buffer, sizeof(buffer); /*这段代码是循环读取文件的一段数据,在循环调用send,发送到客户端,这里强调一点的TCP每次接受最多是1024字节多了就会分片,因此每次发送时尽量不要超

24、过1024字节。*/fclose(fp); printf("File:t%s Transfer Finishedn",file_name); elseprintf("NOT Ready!n"); return 0;int do_get(const char *src, const char *dst, int sock_fd) /从远端服务器下载文件int length = 0;int write_length; /写入文件长度 char file_nameMAX_LENGTH;char bufferMAX_LINE;char b_tMAX_LENGTH

25、; /记录argv1的临时变量FILE * fp;int i = 0,len = 0,j = 0;if( sock_fd < 0) printf("Create Socket Failed!n");exit(1); elseprintf("Creat Socket Scuess!n");write(sock_fd,,sizeof(); /向服务器发送操作符printf(":%sn",); bzero(buffer,sizeof(buffer);strcpy(

26、buffer,src);send(sock_fd,buffer,sizeof(buffer),0);printf("src:%sn",buffer);bzero(buffer,sizeof(buffer);strcpy(buffer,dst);send(sock_fd,buffer,sizeof(buffer),0);printf("dst:%sn",buffer);bzero(buffer,sizeof(buffer);recv(sock_fd,buffer,sizeof(buffer),0); /Readyprintf("From Serv

27、er:%sn",buffer);if(strcmp(buffer,"Ready") = 0)bzero(buffer,sizeof(buffer); bzero(file_name, sizeof(file_name);strcpy(b_t,src);len = strlen(b_t); /*提取文件名*/i = len - 1;while(b_ti != '/')i-;i+;while(i<len)file_namej+ = b_ti;i+; send(sock_fd,file_name,sizeof(file_name),0);print

28、f("File Name :%sn",file_name);strcpy(buffer,dst);/连接文件名和所要放的文件夹位置strcat(buffer,"/");strncat(buffer,file_name,strlen(file_name); fp = fopen(buffer,"w+"); if(NULL = fp ) printf("File:t%s Can Not Open To Writen", file_name); /从服务器接收数据到buffer中 bzero(buffer,sizeof(

29、buffer); while(length = recv(sock_fd,buffer,sizeof(buffer),0) > 0) /循环接收,再写到文件 printf("length:%dn",length); write_length = fwrite(buffer,sizeof(char),length-1,fp);if(write_length = length)if(write_length < MAX_LINE)break; bzero(buffer,sizeof(buffer); if(length < 0) printf("Re

30、cieve Data From Server %s Failed!n",src);exit(1); printf("Recieve File:t %s From Server%s Finishedn",file_name, src); fclose(fp);elseprintf("NOT Ready!n");return 0;int do_serv_cd(char *path, int sock_fd) /进入远端服务器指定目录char bufMAX_LINE = ""write(sock_fd,,size

31、of(); /首先发送操作符strcpy(buf,path);printf("send to server:%sn",buf); send(sock_fd,buf,sizeof(buf),0); bzero(buf,sizeof(buf); recv(sock_fd,buf,sizeof(buf),0); printf("recv from server:%sn",buf);return 0;int do_serv_ls(char *path, int sock_fd) /列出当前服务器目录信息char bufMAX_LINE = &q

32、uot;"write(sock_fd,,sizeof(); /首先发送操作符strcpy(buf,path);printf("send to server:%sn",buf); send(sock_fd,buf,sizeof(buf),0); bzero(buf,sizeof(buf);while(1)bzero(buf,sizeof(buf);recv(sock_fd,buf,sizeof(buf),0);if(strcmp(buf,"Finish") = 0)break; printf("%sn

33、",buf);return 0;int bye(int sock_fd) /退出服务器,关闭连接char buf5 = ""write(sock_fd,"BYE",4);recv(sock_fd,buf,sizeof(buf),0);/printf("%sn",buf);close(sock_fd);printf("Close links!n");return 0;/Client input.c#include "common.h"int input(int *len)char Com

34、mandCOMMAND_LINE = ""/int argv;printf("Please Enter Command And Path!n");gets(Command);*len = strlen(Command);if(strcmp(Command,"bye") = 0)*len = -1;memset(&comd,0, sizeof(comd); argv = split(&comd,Command);return argv;int split(struct command_line *com, char li

35、ne) /拆分命令相关函数char ca_tmpCOMMAND_LINE = ""int i = 0;int j = 0;int k = 0;int flag = 1; int len = strlen(line);for(i = 0;i < 4;i+)com->argvi=(char *)malloc(sizeof(char)*64);for(i = 0;i <= len;i+)if(linei != ' ' && linei != '0')flag = 0;ca_tmpj+ = linei;else if

36、(flag = 0)ca_tmpj = '0'/printf("ca_tmp:%sn",ca_tmp);/com->argvk=(char *)malloc(sizeof(char);strcpy(com->argvk,ca_tmp);/printf("com->a:%sn",com->argvk);flag = 1;j = 0;memset(ca_tmp,0,sizeof(ca_tmp);k+;com->name=(char *)malloc(sizeof(char)*64);strcpy(com->

37、name,com->argv0);return k;/Client Own_Function.c#include "command.h"#ifdef PATH_MAXstatic long pathmax = PATH_MAX;#elsestatic long pathmax = 0;#endifstatic long posix_version = 0;static long xsi_version = 0;/*If PATH_MAX is indeterminate,no guarantee this is adequate*/#define PATH_MAX_G

38、UESS 1024char *path_alloc(size_t *sizep)char *ptr;size_t size;if(posix_version = 0)posix_version = sysconf(_SC_VERSION);if(xsi_version = 0)xsi_version = sysconf(_SC_XOPEN_VERSION);if(pathmax = 0)errno = 0;if(pathmax = pathconf("/",_PC_PATH_MAX) < 0)if(errno = 0)pathmax = PATH_MAX_GUESS;

39、elseprintf("pathconf error for _PC_PATH_MAX");elsepathmax+;if(posix_version < 200112L) && (xsi_version < 4)size = pathmax + 1;elsesize = pathmax;if(ptr = malloc(size) = NULL)printf("malloc error for pathname");if(sizep != NULL)*sizep = size;return(ptr);/Client main.

40、c#include "common.h"int main()int arg = 0;int len = 0;int sock_fd;int res;char ip100 = ""printf("Please enter IPv4 !n");gets(ip);res = do_connect(ip,&sock_fd);if(res != 0)perror("Connect Server Failed!n");/exit(1);while(1)printf("Please enter the comm

41、and to be operating.n");loop:arg = input(&len);if(len = 0)perror("The input is empty,Will be exit!n");sleep(2);goto loop;else if(len = -1)perror("You input 'bye',the programme wil be exit!n");sleep(1);bye(sock_fd);exit(1);if(arg = 2)if(strcmp(,"cd&q

42、uot;) = 0)do_cd(comd.argv1);else if(strcmp(,"ls") = 0)do_ls(comd.argv1);else if(strcmp(,"!cd") = 0)strcpy(,"CD");do_serv_cd(comd.argv1,sock_fd);else if(strcmp(,"!ls") = 0)strcpy(,"LS");do_serv_ls(comd.argv

43、1,sock_fd);else if(arg = 3)if(strcmp(,"get") = 0)strcpy(,"GET");do_get(comd.argv1,comd.argv2,sock_fd);else if(strcmp(,"put") = 0)strcpy(,"PUT");/printf("%d,%d,%dn",sizeof(*(),sizeof(*(comd.argv1),sizeof(*(

44、comd.argv2);/printf("%sn%sn",comd.argv1,comd.argv2);do_put(comd.argv1,comd.argv2,sock_fd);elseprintf("Too many parameters or Too few parameters!n");goto loop;else printf("Too many parameters or Too few parameters!n");goto loop; return 0;/Client Makefile:main:main.o comm

45、and.o Own_Function.o input.ogcc -o main main.o command.o Own_Function.o input.omian.o:main.c gcc -c main.ccommand.o:command.c gcc -c command.cOwn_Function.o:Own_Function.cgcc -c Own_Function.cinput.o:input.cgcc -c input.c.PHONY:cleanclean:rm -rf *.o main服务器端:/Server common.h#include <stdio.h>#

46、include <string.h>#include <stdlib.h>#include <sys/types.h>#include <sys/socket.h>#include <arpa/inet.h>#include <dirent.h>#include <unistd.h>#include <errno.h>#include <limits.h>#define MAX_LINE 1024 /向服务器端发送命令的最大长度#define PORT 8000 /端口号#define

47、COMMAND_LINE 256 /用户输入客户端命令的最大长度#define MAX_LENGTH 64 /每个参数或命令的最大长度int do_connect(char *ip,int *serv,int *sock_fd); /与服务器端进行连接int do_get(const char *src, const char *dst, int sock_fd);/从远端服务器下载文件int do_put(const char *src, const char *dst, int sock_fd);/向远端服务器上传文件int do_cd(char *path,int sock_fd); /

48、进入当前主机指定目录int do_ls(char *path,int sock_fd); /列出当前主机指定目录下的内容char * path_alloc(size_t *sizep); /获取存放完整路径的内存空间起始地址和大小int sock_fd;/Client command.c#include "common.h"int do_connect(char *ip, int *serv,int *sock_fd) /与客户端端进行连接 struct sockaddr_in svraddr,cliaddr; int res; int len; *serv = socke

49、t(PF_INET, SOCK_STREAM, 0); svraddr.sin_family=AF_INET; svraddr.sin_port=htons(1234); inet_pton(AF_INET, "", &(svraddr.sin_addr); res=bind(*serv,(struct sockaddr *)(&svraddr),sizeof(svraddr); if(res != 0) perror("Err in bindn"); exit(1); listen(*serv, 5); len=sizeof(struct sockaddr_in); *so

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论