嵌入式之路,贵在日常点滴
---阿杰在线送代码
本项目为阿杰在过去做过的项目,现在来整理一下。
目录
客户端
1、获取服务器的文件 get xx
2、展示服务器有哪些文件 ls
3、进入服务器某文件夹 cd xx
4、上传文件到服务器 put xx
5、查看客户端本地文件 lls
6、查看进入客户端xx文件夹 ccd xx
服务端:
解析、执行、返回客户端
一个子进程负责一条连接通道
服务端
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include "config.h"
- #include
- #include
- #include
-
-
- int get_cmd_type(char *cmd)
- {
- if(!strcmp("ls",cmd)) return LS;
- if(!strcmp("quit",cmd)) return QUIT;
- if(!strcmp("pwd",cmd)) return PWD;
- if(strstr(cmd,"cd")!=NULL) return CD;
- if(strstr(cmd,"get")!=NULL) return GET;
- if(strstr(cmd,"put")!=NULL) return PUT;
-
- return 100;
- }
-
- char *getDesDir(char *cmsg)
- {
- char *p;
- p = strtok(cmsg," ");
- p = strtok(NULL," ");
-
- return p;
- }
-
- void msg_handler(struct Msg msg,int fd)
- {
- char dataBuf[1024] = {0};
- char *file = NULL;
- int fdfile;
-
- printf("cmd:%s\n",msg.data);
- int ret = get_cmd_type(msg.data);//把字符串转换成想要的整形数
-
- switch(ret){
- case LS:
- case PWD:
- msg.type = 0;
- FILE *r = popen(msg.data,"r");//ls pwd
- fread(msg.data,sizeof(msg.data),1,r);
- write(fd,&msg,sizeof(msg));
- break;
- case CD:
- msg.type = 1;
- char *dir = getDesDir(msg.data);
- printf("dir:%s\n",dir);
- chdir(dir);//改变目录
- break;
- case GET:
- file = getDesDir(msg.data);
-
- if(access(file,F_OK) == -1){
- strcpy(msg.data,"No This File!");
- write(fd,&msg,sizeof(msg));
- }else{
- msg.type = DOFILE;
- fdfile = open(file,O_RDWR);
- read(fdfile,dataBuf,sizeof(dataBuf));
- close(fdfile);
-
- strcpy(msg.data,dataBuf);
- write(fd,&msg,sizeof(msg));
- }
-
- break;
- case PUT:
- fdfile = open(getDesDir(msg.data),O_RDWR|O_CREAT,0666);
- write(fdfile,msg.secondBuf,strlen(msg.secondBuf));
- close(fdfile);
- break;
- case QUIT:
- printf("client quit!\n");
- exit(-1);
- }
- }
-
- int main(int argc,char **argv)
- {
- int s_fd;
- int c_fd;
- int n_read;
- char readbuf[128] = {0};
-
- struct sockaddr_in s_addr;
- struct sockaddr_in c_addr;
- struct Msg msg;
-
- memset(&s_addr,0,sizeof(struct sockaddr_in));
- memset(&c_addr,0,sizeof(struct sockaddr_in));
-
- if(argc != 3){//参数判断
- printf("param is not good\n");
- exit(-1);
- }
-
- //1.socket
- s_fd = socket(AF_INET,SOCK_STREAM,0);
- if(s_fd == -1)
- {
- perror("sccket");
- exit(-1);
- }
-
- //2.bind
- s_addr.sin_family = AF_INET;
- s_addr.sin_port = htons(atoi(argv[2]));
- inet_aton(argv[1],&s_addr.sin_addr);
- bind(s_fd,(struct sockaddr *)&s_addr,sizeof(struct sockaddr_in));
-
- //3.listen
- listen(s_fd,10);
-
- //4.accept
- int clen;
- clen = sizeof(struct sockaddr_in);
- //为实现双方聊天的关键点,死循环,一直执行在这里,不让程序退出
- while(1){
- c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&clen);
- if(c_fd == -1)
- {
- perror("accept");
- }
-
- printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));
-
- if(fork() == 0)
- {//fork() == 0子进程用来发
- while(1)
- {
- memset(msg.data,0,sizeof(msg.data));
- n_read = read(c_fd, &msg, sizeof(msg));
- //zai zhe li du,du bu dao hui zu sai zai zhe li
- if(n_read == 0){
- printf("client out\n");
- break;
- }else if(n_read > 0){
- msg_handler(msg,c_fd);
- }
- }
- }
- }
-
- close(c_fd);
- close(s_fd);
- return 0;
- }
客户端
- #include
- #include
- #include
- #include
- #include
- #include
- #include
- #include "config.h"
- #include
- #include
- #include
-
- int get_cmd_type(char *cmd)
- {
- if(strstr(cmd,"lcd")!=NULL) return LCD;
-
- if(!strcmp("lls",cmd)) return LLS;
- if(!strcmp("ls",cmd)) return LS;
- if(!strcmp("quit",cmd)) return QUIT;
- if(!strcmp("pwd",cmd)) return PWD;
-
- if(strstr(cmd,"cd")!=NULL) return CD;
- if(strstr(cmd,"get")!=NULL) return GET;
- if(strstr(cmd,"put")!=NULL) return PUT;
-
- return -1;
- }
-
- char *getdir(char *cmd)
- {
- char *p;
-
- p = strtok(cmd," ");
- p = strtok(NULL," ");
-
- return p;
- }
-
- int cmd_handler(struct Msg msg,int fd)
- {
- char *dir = NULL;
- char buf[32];
- int ret;
- int filefd;
-
- ret = get_cmd_type(msg.data);
-
- switch(ret){
- case LS:
- case CD:
- case PWD:
- msg.type = 0;
- write(fd,&msg,sizeof(msg));
- break;
- case GET:
- msg.type = 2;
- write(fd,&msg,sizeof(msg));
- break;
- case PUT:
- strcpy(buf,msg.data);
- dir = getdir(buf);
-
- if(access(dir,F_OK) == -1){
- printf("%s not exsit\n",dir);
- }else{
- filefd = open(dir,O_RDWR);
- read(filefd,msg.secondBuf,sizeof(msg.secondBuf));
- close(filefd);
-
- write(fd,&msg,sizeof(msg));
- }
- break;
- case LLS:
- system("ls");
- break;
- case LCD:
- dir = getdir(msg.data);
- chdir(dir);
- break;
- case QUIT:
- strcpy(msg.data,"quit");
- write(fd,&msg,sizeof(msg));
- close(fd);
- exit(-1);
- }
-
- return ret;
- }
-
- void handler_server_message(int c_fd,struct Msg msg)
- {
- int n_read;
- struct Msg msgget;
- int newfilefd;
-
- n_read = read(c_fd,&msgget,sizeof(msgget));
-
- if(n_read == 0){
- printf("server is out,quit\n");
- exit(-1);
- }
-
- else if(msgget.type == DOFILE){
- char *p = getdir(msg.data);
- newfilefd = open(p,O_RDWR|O_CREAT,0600);
- write(newfilefd,msgget.data,strlen(msgget.data));
- putchar('>');
- fflush(stdout);
- }
-
- else{
- printf("------------------------------\n");
- printf("\n%s\n",msgget.data);
- printf("------------------------------\n");
-
- putchar('>');
- fflush(stdout);
- }
-
- }
-
- int main(int argc,char **argv)
- {
- int c_fd;
-
- struct Msg msg;
- struct sockaddr_in c_addr;
- memset(&c_addr,0,sizeof(struct sockaddr_in));
-
- if(argc != 3){
- printf("param is not good\n");
- exit(-1);
- }
-
- //1.socket
- c_fd = socket(AF_INET,SOCK_STREAM,0);
- if(c_fd == -1)
- {
- perror("sccket");
- exit(-1);
- }
-
- //2.connect
- c_addr.sin_family = AF_INET;
- c_addr.sin_port = htons(atoi(argv[2]));
- inet_aton(argv[1],&c_addr.sin_addr);
- if(connect(c_fd,(struct sockaddr *)&c_addr,sizeof(struct sockaddr_in)) == -1)
- {
- perror("connect");
- exit(-1);
- }
- printf("connect ...\n");
- int mark = 0;
-
- while(1)
- {
- memset(msg.data,0,sizeof(msg.data));
- if(mark == 0) printf(">");
-
- gets(msg.data);
-
- if(strlen(msg.data) == 0){
- if(mark == 1){
- printf(">");
- }
- continue;
- }
-
- mark = 1;
-
- int ret = cmd_handler(msg,c_fd);
-
- if(ret>IFGO){
- putchar('>');
- fflush(stdout);//?
- continue;
- }
- if(ret == -1){
- printf("command not \n");
- printf(">");
- fflush(stdout);
- continue;
- }
- handler_server_message(c_fd,msg);
- }
-
- return 0;
- }
宏定义
- #define LS 0
- #define GET 1
- #define PWD 2
-
- #define IFGO 3
-
- #define LCD 4
- #define LLS 5
- #define CD 6
- #define PUT 7
-
- #define QUIT 8
- #define DOFILE 9
-
- struct Msg
- {
- int type;
- char data[1024];
- char secondBuf[128];
- };
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)刷新标准输出缓冲区,把输出缓冲区里的东西打印到标准输出设备上