首页 > 其他分享 >模拟ftp服务器

模拟ftp服务器

时间:2024-02-28 15:45:29浏览次数:14  
标签:ftp return int cmd fd msg 服务器 data 模拟

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

相关文章

  • NFLS 省选模拟 过路费
    前言这道题正向思考是比较难以想出来的,蕴含了一类解题的思路,同时也可以当作一类板子题记忆。题面Link给定一个有向图,求\(s\)到\(t\)的最短路径。特殊点在于,对于一条路径,如果经过的边数小于等于\(k\),那么该路径总长度为构成该路径的所有边的长度之和;否则为该路径上最长的......
  • 模拟量系数计算方法(y = ax + b)
    客户测量范围是M—N(M < N),采集数据范围X—Y(X < Y)计算公式:y = ax + bM = Xa + b N = Ya + b 得:N - M = (Y - X)a 进一步可得:a = (N - M)/ (Y - X)利用二元一次方程可得 b 的值 测量水的深为例:(1)水的测量范围为0-10米,(2)模拟量转485为低精度(4-20mA,数据采......
  • 北斗同步时钟服务器(NTP网络时间服务器)应用于计算机网络系统
    北斗同步时钟服务器(NTP网络时间服务器)应用于计算机网络系统北斗同步时钟服务器(NTP网络时间服务器)应用于计算机网络系统京准电子科技官微——ahjzsz前言近几年来,随着计算机自动化系统水平的提高,在各大计算机监控系统、微机保护装置、微机故障录波装置以及各类数据管理机得......
  • VSCode SSH连接服务器
    使用场景:本地VSCode通过SSH访问(远程)服务器通过SSH连接远程服务器:sshuser@hostname(SSH默认端口为22),然后提示需要输入登录密码参考:https://code.visualstudio.com/docs/remote/ssh后续TODO:generateSSHkey参考资料:https://zhuanlan.zhihu.com/p/294933020......
  • GDOI2024 考前模拟2 T2
    题目描述题解考虑黑用\(1\)表示,白用\(0\)表示,那么Alice要赢,就意味着每条边\(x\rightarrowy\)等价于\(clr[x]\leclr[y]\)。连边也就是\(\le\)的关系。不妨编号从\(0\)开始,题目的染色方式则意味着\(clr[x]\neqclr[x\bigoplus1]\)。那么原图里有\(x\rightarrow......
  • ubuntu20.04开启ftp服务
    sudoaptupdatesudoaptinstallvsftpdsudovi/etc/vsftpd.conflocal_enable=YES允许本地用户通过FTP登录到服务器 取消注释并将其设置为:chroot_local_user=YES这将限制本地用户的FTP访问仅限于其家目录。 sudosystemctlstartvsftpd#启动sudosystemctl......
  • 更改pureftpd vsftpd与proftpd的默认端口(转载)
    tp的默认端口是21,但如果启用ftp且开放21端口,经常会受到各种工具尝试破解ftp密码,且说你的ftp密码非常的强大,几乎不能暴力破解,但是工具暴力破解ftp密码时需要消耗系统资源,所以我们干脆更改下ftp的端口,这样就可以防止了各种暴力破解工具的侵扰。下面www.centos.bz把21端口更改为2121......
  • pure-ftpd安装与使用(转载)
    一、摘要FTP是FileTransferProtocol(文件传输协议)的英文简称,而中文简称为"文传协议”。用于Internet上的控制文件的双向传输。同时,它也是一个应用程序(Application)。基于不同的操作系统有不同的FTP应用程序,而所有这些应用程序都遵守同一种协议以传输文件。在FTP的使用当中,用户......
  • psql: 无法联接到服务器: 没有那个文件或目录 服务器是否在本地运行并且在 Unix 域套
    今天在服务器上用root用户输入pgsql和pg_dump报错如下 首先检查了下pg的状态发现正常systemctlstatuspostgresql 然后尝试输入pg_dump-h127.0.0.1psql-h127.0.0.1不再报错 添加了-h127.0.0.1原因未知,待解决...... 第二次尝试添加了环境变量vim /et......
  • STL-unordered_map,unordered_set模拟实现
    unordered_set#pragmaonce#include"28hashtable_container.h"namespacetest{//template<//classKey,//unordered_set::key_type/value_type//classHash=hash<Key>,//unordered_s......