client.c
int get_cmd_type(char *cmd) { //比较输入的指令,找到对应的就返回相对应的指令。 if(!strcmp("ls",cmd)) return LS; if(!strcmp("lls",cmd)) return LLS; if(!strcmp("pwd",cmd)) return PWD; if(!strcmp("quit",cmd)) return QUIE; //在输入的指令字符串里面找,对应的指令 if(strstr(cmd."cd")) return CD; if(strstr(cmd,"get")) return GET; if(strstr(cmd,"put")) return PUT; return -1;//未找到返回错误 } char *getdir(char *cms)//分割指令,来获取参数 { char *p = NULL; p = strtok(cms," "); p = strtok(NULL," "); return p; } int cmd_handler(struct Msg msg,int fd) { int ret; char buf[100];//临时空间 char *dir = NULL; int filefd; //文件表示符 ret = get_cmd_type(msg.data);//输入的指令转换成整数 switch(ret)//根据ret的值来选择 { case PWD: case LS: case CD: msg.type = 0;//标记符 write(fd,msg.data,sizeof(msg));//发送命令 break; case GET: msg.type = 2; write(fd,msg.data,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.buf,sizeof(msg.buf));//读取这个文件 close(filefd);//关闭这个文件 write(fd,msg,data,sizeof(msg));//向服务器发送命令 } case QUIT: strcpy(msg.data,"quit"); write(fd,msg.data,sizeof(msg)); close(fd);//关闭文件 exit(-1);//退出程序 case LLS: system("ls"); break; case LCD: dir = getdir(msg.data); chdir(dir); break; } return ret; } void hand_sever_message(int c_fd,struct Msg msg) { struct Msg msgget; char *dir = NULL; int n_read; n_read = read(c_fd,&msgget,sizeof(msgget));//客户端执行到这里时,会阻塞在这,等待服务器写入数据 if(n_read == -1) { printf("server out \n"); exit(-1); } else if(msg.type == DOFILE) { dir = getdir(msg.data); int filefd = open(dir,O_RDWR|O_CREAT,0666); write(filefd,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; int ret; struct Msg msg;//定义结构体 struct sockaddr_in c_addr; memset(&c_addr,0,sizeof(struct sockaddr));//初始化结构体里的内容 c_fd = socket(AF_INET,SOCK_STREAM,0);//创建socket if(c_fd==-1) { perror("socket:"); exit(-1); } c_addr.sin_family = AF_INET; c_addr.sin_port =htons(atoi(argv[2])); inet_aton(argv[1], &c_addr.sin_addr); connect(c_fd,(struct sockaddr*)&c_addr,sizeof(struct sockaddr_in));//请求连接 printf("get connect:%s\n",inet_ntoa(c_addr.sin_addr));//连接成功打印IP while(1) { memset(msg.data,0,sizeof(msg.data)); scanf("%[\n]",msg.data);//获取客户端指令 if(strlen(msg.data) == 0) { if(mark == 1) { printf(">"); } } ret = cmd_handler(msg,c_fd);//封装一个函数,处理指令 if(ret >IFGO) { putchar('>'); fflush(stdout); continue; } if(ret == -1) { printf("commend out\n"); printf(">"); fflush(stdout); } handler_sever_message(c_fd,msg);//处理客户端返回内容 } close(c_fd);//关闭文件 return 0; }
server.c
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 -1; } char *getdir(char cmd)//分割指令,获取第二个参数 { char *p = NULL; p = strtok(cmd," "); p = strtok(NULL," "); return p; } void msg_handler(struct Msg msg,int fd) { int ret; char *dir; char *databuf[1024] = {0};//临时空间 int fdfile;//文件描述符 ret = get_cmd_type(msg.data); switch(ret) case LS: case PWD: msg.type = 0 FILE *r = popen(msg.data,"r");执行该参数,并读取,返回读取文件的指针 fread(msg.data,sizeof(msg.data),1,r);读取到data空间里面,读取一次,读取的文件是上面r指向的文件。 write(fd,msg.data,sizeof(msg));读取完成后写入。 break; case CD: dir = getdir(msg.data);//先把指令分割出来,获取参数 printf("dir :%s\n",dir);//打印参数 chdir(dir); 将当前目录改向参数指向的目录。 break; case GET: dir = getdir(msg.data);//获取参数文件 if(access(dir,F_OK)== -1)//判断文件存在吗 { strcpy(msg.data,"NO this file"); } else//如果存在 { msg.type = DOFILE; //标记 fdfile = open(dir,O_RDWR);//打开此文件 read(fdfile,databuf,sizeof(databuf));//读取此文件到临时空间databuf里面 close(fdfile);//读取完成,关闭此文件 strcpy(msg.data,databuf);//将databuf拷贝 write(fd,msg.data,sizeof(msg));//写入 } break; case PUT: dir = getdir(msg.data);//分割获取第二个参数 fdfile = open(dir,O_RDWR|O_CREAT,0666);//打开该参数的文件 write(fd,msg.buf,strlen(msg.buf));//将客户端读取的内容写入服务器 close(fdfile);//写完关闭文件 break; case QUIT: printf("client quit\n");//打印退出信心 exit(-1);//退出程序 } int main(int argc,char**argv) { if(argc !=3 )//判断参数是否输入正确 { printf("input errror\n"); exit(-1); } int s_fd = socket(AF_INET,SOCK_STREAM,0);//创建网络套接字 struct Msg msg; struct sockaddr_in addr; struct sockaddr_in addr2; memset(&addr,0,sizeof(struct sockaddr_in)); memset(&addr2,0,sizeof(struct sockaddr_in)); int n_read; addr.sin_family = AF_INET;//地址协议族 addr.sin_prot = htons(atoi(argv[2]));//端口号,先使用atoi函数把参数转换成整型,在使用htons转为网络字节序。 inet_aton(argv[1], &s_addr.sin_addr);//IP地址,使用inet_aton函数把点分十进制的IP地址,转换为网络字节序。例如,192.168.147.155. bind(s_fd,(struct sockaddr*)&addr,sizeof(struct sockaddr_in)); listen(s_fd,10);//监听 int sz = sizeof(struct sockaddr_in); while(1)//循环卡住不让退出去。 { int c_fd = accept(s_fd,(struct sockaddr *)&addr2,&sz);//尝试连接 if(c_fd == -1) { perror("accept"); exit(-1); } printf("get connect : %s\n",inet_nota(addr2.sin_addr));//连接成功打印对方的IP地址。 if(fork()== 0)//创建子进程来对接,进行通讯 { memset(msg.data,0,sizeof(msg.date)); n_read =read(c_fd,&msg,sizeof(msg));//读取客户端发过来的消息 if(n_read == 0)//判断读取信息 { printf("client out\n"); break; }else (if n_read>0)//如果读取到了 { msg_hanfler(msg,c_fd);//处理函数 } } } return 0; }
common.h
#include<stdio.h> #include <sys/types.h> #include <sys/socket.h> #include <arpa/inet.h> #include <netinet/in.h> #include<stdlib.h> #include<string.h> #include <unistd.h> #include <fcntl.h> #define LS 0 #define PWD 1 #define GET 2 #define IFGO 3 #define CD 4 #define PUT 5 #define LLS 6 #define LCD 7 #define LPWD 8 #define QUIT 9 #define DOFILE 10 struct Msg { int type; char data[1024]; char buf[128]; };
标签:ftp,return,int,cmd,fd,msg,服务器,data,模拟 From: https://www.cnblogs.com/zj-studyrecoding/p/18040648