主要代码
config.h
#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];
};
服务器:
#include <stdio.h>
#include <sys/types.h> /* See NOTES */
#include <sys/socket.h>
// #include<linux/in.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "config.h"
#include <sys/stat.h>
#include <fcntl.h>
int get_cmd_type(char *cmd)
{
if (!strcmp("ls", cmd))
return LS; // 这里类命令没有参数直接strcmp 比较即可
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;
}
char *getDesDir(char *cmsg) // 获取后段字符串 --- 参数
{
char *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:
// popen() 函数通过创建一个管道,调用 fork 产生一个子进程,执行一个 shell 以运行命令来开启一个进程。
FILE *r = popen(msg.data, "r");
fread(msg.data, sizeof(msg.data), 1, r);
write(fd, &msg, sizeof(msg)); // 写入socket通道的 fd
break;
case CD:
char *dir = getDesDir(msg.data);
printf("dir: %s\n", dir);
chdir(dir);
break;
case GET:
msg.type=DOFILE;
file = getDesDir(msg.data); //// 获取后段字符串 --- 参数 -文件名
if (access(file, F_OK) == -1)
{ // access 判断文件是否存在
strcpy(msg.data, "No this file!"); ////将 "no this file"的信息写入data,并且write返回给客户端
write(fd, &msg,