• 基于Linux的无界面网盘 项目


    嵌入式之路,贵在日常点滴

                                                                    ---阿杰在线送代码

    本项目为阿杰在过去做过的项目,现在来整理一下。

    目录

    一、功能

    二、项目总结

    三、项目经验 

    四、项目代码

    五、一些不太熟悉的API


    一、功能


    客户端 

    1、获取服务器的文件 get xx        
    2、展示服务器有哪些文件 ls
    3、进入服务器某文件夹 cd xx
    4、上传文件到服务器 put xx


    5、查看客户端本地文件 lls
    6、查看进入客户端xx文件夹 ccd xx

    服务端:
    解析、执行、返回客户端 


    二、项目总结

    三、项目经验 

    一个子进程负责一条连接通道 

    四、项目代码

    服务端

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include "config.h"
    9. #include
    10. #include
    11. #include
    12. int get_cmd_type(char *cmd)
    13. {
    14. if(!strcmp("ls",cmd)) return LS;
    15. if(!strcmp("quit",cmd)) return QUIT;
    16. if(!strcmp("pwd",cmd)) return PWD;
    17. if(strstr(cmd,"cd")!=NULL) return CD;
    18. if(strstr(cmd,"get")!=NULL) return GET;
    19. if(strstr(cmd,"put")!=NULL) return PUT;
    20. return 100;
    21. }
    22. char *getDesDir(char *cmsg)
    23. {
    24. char *p;
    25. p = strtok(cmsg," ");
    26. p = strtok(NULL," ");
    27. return p;
    28. }
    29. void msg_handler(struct Msg msg,int fd)
    30. {
    31. char dataBuf[1024] = {0};
    32. char *file = NULL;
    33. int fdfile;
    34. printf("cmd:%s\n",msg.data);
    35. int ret = get_cmd_type(msg.data);//把字符串转换成想要的整形数
    36. switch(ret){
    37. case LS:
    38. case PWD:
    39. msg.type = 0;
    40. FILE *r = popen(msg.data,"r");//ls pwd
    41. fread(msg.data,sizeof(msg.data),1,r);
    42. write(fd,&msg,sizeof(msg));
    43. break;
    44. case CD:
    45. msg.type = 1;
    46. char *dir = getDesDir(msg.data);
    47. printf("dir:%s\n",dir);
    48. chdir(dir);//改变目录
    49. break;
    50. case GET:
    51. file = getDesDir(msg.data);
    52. if(access(file,F_OK) == -1){
    53. strcpy(msg.data,"No This File!");
    54. write(fd,&msg,sizeof(msg));
    55. }else{
    56. msg.type = DOFILE;
    57. fdfile = open(file,O_RDWR);
    58. read(fdfile,dataBuf,sizeof(dataBuf));
    59. close(fdfile);
    60. strcpy(msg.data,dataBuf);
    61. write(fd,&msg,sizeof(msg));
    62. }
    63. break;
    64. case PUT:
    65. fdfile = open(getDesDir(msg.data),O_RDWR|O_CREAT,0666);
    66. write(fdfile,msg.secondBuf,strlen(msg.secondBuf));
    67. close(fdfile);
    68. break;
    69. case QUIT:
    70. printf("client quit!\n");
    71. exit(-1);
    72. }
    73. }
    74. int main(int argc,char **argv)
    75. {
    76. int s_fd;
    77. int c_fd;
    78. int n_read;
    79. char readbuf[128] = {0};
    80. struct sockaddr_in s_addr;
    81. struct sockaddr_in c_addr;
    82. struct Msg msg;
    83. memset(&s_addr,0,sizeof(struct sockaddr_in));
    84. memset(&c_addr,0,sizeof(struct sockaddr_in));
    85. if(argc != 3){//参数判断
    86. printf("param is not good\n");
    87. exit(-1);
    88. }
    89. //1.socket
    90. s_fd = socket(AF_INET,SOCK_STREAM,0);
    91. if(s_fd == -1)
    92. {
    93. perror("sccket");
    94. exit(-1);
    95. }
    96. //2.bind
    97. s_addr.sin_family = AF_INET;
    98. s_addr.sin_port = htons(atoi(argv[2]));
    99. inet_aton(argv[1],&s_addr.sin_addr);
    100. bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
    101. //3.listen
    102. listen(s_fd,10);
    103. //4.accept
    104. int clen;
    105. clen = sizeof(struct sockaddr_in);
    106. //为实现双方聊天的关键点,死循环,一直执行在这里,不让程序退出
    107. while(1){
    108. c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);
    109. if(c_fd == -1)
    110. {
    111. perror("accept");
    112. }
    113. printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));
    114. if(fork() == 0)
    115. {//fork() == 0子进程用来发
    116. while(1)
    117. {
    118. memset(msg.data,0,sizeof(msg.data));
    119. n_read = read(c_fd, &msg, sizeof(msg));
    120. //zai zhe li du,du bu dao hui zu sai zai zhe li
    121. if(n_read == 0){
    122. printf("client out\n");
    123. break;
    124. }else if(n_read > 0){
    125. msg_handler(msg,c_fd);
    126. }
    127. }
    128. }
    129. }
    130. close(c_fd);
    131. close(s_fd);
    132. return 0;
    133. }

    客户端

    1. #include
    2. #include
    3. #include
    4. #include
    5. #include
    6. #include
    7. #include
    8. #include "config.h"
    9. #include
    10. #include
    11. #include
    12. int get_cmd_type(char *cmd)
    13. {
    14. if(strstr(cmd,"lcd")!=NULL) return LCD;
    15. if(!strcmp("lls",cmd)) return LLS;
    16. if(!strcmp("ls",cmd)) return LS;
    17. if(!strcmp("quit",cmd)) return QUIT;
    18. if(!strcmp("pwd",cmd)) return PWD;
    19. if(strstr(cmd,"cd")!=NULL) return CD;
    20. if(strstr(cmd,"get")!=NULL) return GET;
    21. if(strstr(cmd,"put")!=NULL) return PUT;
    22. return -1;
    23. }
    24. char *getdir(char *cmd)
    25. {
    26. char *p;
    27. p = strtok(cmd," ");
    28. p = strtok(NULL," ");
    29. return p;
    30. }
    31. int cmd_handler(struct Msg msg,int fd)
    32. {
    33. char *dir = NULL;
    34. char buf[32];
    35. int ret;
    36. int filefd;
    37. ret = get_cmd_type(msg.data);
    38. switch(ret){
    39. case LS:
    40. case CD:
    41. case PWD:
    42. msg.type = 0;
    43. write(fd,&msg,sizeof(msg));
    44. break;
    45. case GET:
    46. msg.type = 2;
    47. write(fd,&msg,sizeof(msg));
    48. break;
    49. case PUT:
    50. strcpy(buf,msg.data);
    51. dir = getdir(buf);
    52. if(access(dir,F_OK) == -1){
    53. printf("%s not exsit\n",dir);
    54. }else{
    55. filefd = open(dir,O_RDWR);
    56. read(filefd,msg.secondBuf,sizeof(msg.secondBuf));
    57. close(filefd);
    58. write(fd,&msg,sizeof(msg));
    59. }
    60. break;
    61. case LLS:
    62. system("ls");
    63. break;
    64. case LCD:
    65. dir = getdir(msg.data);
    66. chdir(dir);
    67. break;
    68. case QUIT:
    69. strcpy(msg.data,"quit");
    70. write(fd,&msg,sizeof(msg));
    71. close(fd);
    72. exit(-1);
    73. }
    74. return ret;
    75. }
    76. void handler_server_message(int c_fd,struct Msg msg)
    77. {
    78. int n_read;
    79. struct Msg msgget;
    80. int newfilefd;
    81. n_read = read(c_fd,&msgget,sizeof(msgget));
    82. if(n_read == 0){
    83. printf("server is out,quit\n");
    84. exit(-1);
    85. }
    86. else if(msgget.type == DOFILE){
    87. char *p = getdir(msg.data);
    88. newfilefd = open(p,O_RDWR|O_CREAT,0600);
    89. write(newfilefd,msgget.data,strlen(msgget.data));
    90. putchar('>');
    91. fflush(stdout);
    92. }
    93. else{
    94. printf("------------------------------\n");
    95. printf("\n%s\n",msgget.data);
    96. printf("------------------------------\n");
    97. putchar('>');
    98. fflush(stdout);
    99. }
    100. }
    101. int main(int argc,char **argv)
    102. {
    103. int c_fd;
    104. struct Msg msg;
    105. struct sockaddr_in c_addr;
    106. memset(&c_addr,0,sizeof(struct sockaddr_in));
    107. if(argc != 3){
    108. printf("param is not good\n");
    109. exit(-1);
    110. }
    111. //1.socket
    112. c_fd = socket(AF_INET,SOCK_STREAM,0);
    113. if(c_fd == -1)
    114. {
    115. perror("sccket");
    116. exit(-1);
    117. }
    118. //2.connect
    119. c_addr.sin_family = AF_INET;
    120. c_addr.sin_port = htons(atoi(argv[2]));
    121. inet_aton(argv[1],&c_addr.sin_addr);
    122. if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in)) == -1)
    123. {
    124. perror("connect");
    125. exit(-1);
    126. }
    127. printf("connect ...\n");
    128. int mark = 0;
    129. while(1)
    130. {
    131. memset(msg.data,0,sizeof(msg.data));
    132. if(mark == 0) printf(">");
    133. gets(msg.data);
    134. if(strlen(msg.data) == 0){
    135. if(mark == 1){
    136. printf(">");
    137. }
    138. continue;
    139. }
    140. mark = 1;
    141. int ret = cmd_handler(msg,c_fd);
    142. if(ret>IFGO){
    143. putchar('>');
    144. fflush(stdout);//?
    145. continue;
    146. }
    147. if(ret == -1){
    148. printf("command not \n");
    149. printf(">");
    150. fflush(stdout);
    151. continue;
    152. }
    153. handler_server_message(c_fd,msg);
    154. }
    155. return 0;
    156. }

    宏定义

    1. #define LS 0
    2. #define GET 1
    3. #define PWD 2
    4. #define IFGO 3
    5. #define LCD 4
    6. #define LLS 5
    7. #define CD 6
    8. #define PUT 7
    9. #define QUIT 8
    10. #define DOFILE 9
    11. struct Msg
    12. {
    13. int type;
    14. char data[1024];
    15. char secondBuf[128];
    16. };

    五、一些不太熟悉的API


    int chdir(const char *path ); 调用进程更改了目录
    说明:chdir函数用于改变当前工作目录。调用参数是指向目录的指针,调用进程需要有搜索整个目录的权限。每个进程都具有一个当前工作目录。在解析相对目录引用时,该目录是搜索路径的开始之处。如果调用进程更改了目录,则它只对该进程有效,而不能影响调用它的那个进程。在退出程序时,shell还会返回开始时的那个工作目录。

    要用chdir(原因如果调用进程更改了目录,则它只对该进程有效,而不能影响调用它的那个进程。)
    服务器是一个shell  客户端是一个shell
    如果使用system它会另起一个shell,在这个shell里面去进入某个文件夹。那么这样子原本服务端的shell并没有得到改变,那么你使用ls或者pwd显示的工作目录是没有改变的


    access 判断文件夹是否存在
    头文件:unistd.h
    功 能: 确定文件或文件夹的访问权限。即,检查某个文件的存取方式,比如说是只读方式、只写方式等。如果指定的存取方式有效,则函数返回0,否则函数返回-1。
    用 法: int access(const char *filenpath, int mode); 或者int _access( const char *path, int mode );
    参数说明:
    filenpath
    文件或文件夹的路径,当前目录直接使用文件或文件夹名(使用绝对路径)
    备注:当该参数为文件的时候,access函数能使用mode参数所有的值,当该参数为文件夹的时候,access函数值能判断文件夹是否存在。在WINNT 中,所有的文件夹都有读和写权限
    mode
    要判断的模式
    在头文件unistd.h中的预定义如下:
    #define R_OK 4 /* Test for read permission. */
    #define W_OK 2 /* Test for write permission. https://baike.baidu.com/item/access%E5%87%BD%E6%95%B0/9011017*/
    #define X_OK 1 /* Test for execute permission. */
    #define F_OK 0 /* Test for existence. */
    具体含义如下:
    R_OK 只判断是否有读权限
    W_OK 只判断是否有写权限
    X_OK 判断是否有执行权限
    F_OK 只判断是否存在
    access函数程序范例(C语言中)
    /*int access(const char *pathname, int mode);
    此函数用于检测某个指定路径的文件(第一个参数 pathname),是否符合第二个参数选项(F_OK(是否是存在的文件),R_OK(是否可读),W_OK(是否可以写入),X_OK(是否可以运行);当参数1满足参数2条件时候返回0,不满足返回-1;(此处刚刚好和字符串比对返回值类似)*/

    fflush
    函数名: fflush
    功 能: 清除读写缓冲区,在需要立即把输出缓冲区的数据进行物理写入时
    头文件:stdio.h
    原型:int fflush(FILE *stream)
    其中stream是要冲洗的流
    fflush(stdin)刷新标准输入缓冲区,把输入缓冲区里的东西丢弃[非标准]
    fflush(stdout)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上

     

  • 相关阅读:
    在windows10下VSCode进行shell开发
    【系统设计系列】 应用层与微服务
    推荐10个地推拉新app推广接单平台,都是一手单 官签渠道
    【计算机视觉 | 实例分割】干货:实例分割常见算法介绍合集
    新手如何使用腾讯云云服务器详细教程
    移动WEB开发之流式布局--二倍图
    lambdaQueryWrapper常用方法
    排序算法可视化
    2023软件测试高频面试题
    Go语言基础-基础语法
  • 原文地址:https://blog.csdn.net/weixin_50546241/article/details/126277693