Linux文件服务站(C语言)

服务端代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
#define LS      0
#define PWD     1
#define GET     2
#define CD      3
 
#define IFGO    4
 
#define LLS     5
#define LCD     6
#define PUT     7
#define QUIT    8
#define DOFILE  9
 
struct msg
{
    int type;
    char cmd[1024];        //存放命令和文件数据
    char secondBuf[1024];   //存放文件内容
};
 
int get_cmd_type(char* cmd)//把字符串转成整型数
{
        //int strcmp(const char *s1, const char *s2);//字符串比较
        if(strcmp("ls",cmd) == 0)         return LS;
        if(strcmp("quit",cmd) == 0)       return QUIT;
        if(strcmp("pwd",cmd) == 0)        return PWD;
        //char *strstr(const char *haystack, const char *needle);//搜索一个字符串在另一个字符串中的第一次出现
        if(strstr(cmd,"cd") != NULL)      return CD;
        if(strstr(cmd,"get") != NULL)     return GET;
        if(strstr(cmd,"put") != NULL)     return PUT;
 
        return 250;
}
 
char* get_dir(char* cmd)//分割字符串
{
        char* fp;
        //char *strtok(char *s, char *delim)//分解字符串 str 为一组字符串,delim 为分隔符,返回值:分隔符匹配到的第一个子串
        fp=strtok(cmd,"|");
        fp=strtok(NULL,"|");
        return fp;
}
 
void msgs_Handler(struct msg msgs,int cfd)
{
        int ret;
        char* filename=NULL;
        int fdfile;
        FILE* fp=NULL;
        char* dir=NULL;
 
        char dataBuf[1024]={"\0"};
 
        ret=get_cmd_type(msgs.cmd);//把字符串转成整型数
 
        printf("cmd:%s\n",msgs.cmd);//打印客户端输出的指令      
        printf("ret:%d\n",ret);
 
        switch(ret)
        {
                case PWD:
                case LS:
                        //FILE *popen(const char *command, const char *type);
                        fp=popen(msgs.cmd,"r");
                        fread(msgs.cmd,sizeof(msgs.cmd),1,fp);
                        write(cfd,&msgs,sizeof(msgs));
                        break;
 
                case CD:
                        dir=get_dir(msgs.cmd);//通过该函数获取文件名字
                        printf("dir:%s\n",dir);
                        //int chdir(const char *path)//改变当前工作目录
                        chdir(dir);//dir目录,ch,change,改变
                        break;
 
                case GET:
                        filename=get_dir(msgs.cmd);//获取要操作的文件名(即指令后面的文件名字)
                        //int access(const char* pathname, int mode);//F_OK 值为0,判断文件是否存在
                        if(access(filename,F_OK) == -1)//判断该文件是否存在
                        {
                                strcpy(msgs.cmd,"No this file!");
                                write(cfd,&msgs,sizeof(msgs));
                        }
                        else
                        {
                        //      msgs.type = DOFILE;
                                fdfile=open(filename,O_RDWR);//存在文件就打开文件
                                read(fdfile,dataBuf,sizeof(dataBuf));//读取信息
                                close(fdfile);//关闭文件
 
                                strcpy(msgs.cmd,dataBuf);//将读取的内容复制到cmd数组
                                write(cfd,&msgs,sizeof(msgs));//将读取的内容发送到客户端                        
                                //close(fdfile);//关闭文件
                        }
                                break;
                case PUT:
                        filename=get_dir(msgs.cmd);//获取文件名称
                        fdfile=open(filename,O_RDWR|O_CREAT,0666);//有就打开文件,没有就创建文件
                        write(fdfile,msgs.secondBuf,strlen(msgs.secondBuf));//写内容到目标文件
                        close(fdfile);
                        break;
 
                case QUIT:
                        printf("client quit!\n");
                        exit(-1);
                        break;
        }
 
}
 
int main(int argc,char** argv)
{
 
        if(argc != 3)//判断传入参数是否有三个
        {
                printf("program error!\n");
                exit(-1);
        }
 
        int sfd;
        int cfd;
        int nread;
        struct msg msgs;
 
        struct sockaddr_in s_addr;
        struct sockaddr_in c_addr;
        memset(&s_addr,0,sizeof(struct sockaddr_in));
        memset(&c_addr,0,sizeof(struct sockaddr_in));
 
        //1.socket//创建套接字
        //int socket(int domain, int type, int protocol);
 
        sfd=socket(AF_INET,SOCK_STREAM,0);
        if(sfd == -1)//判断是否创建成功
        {
                perror("socket");
                exit(-1);
        }
 
        //2.bind//绑定IP号及端口
        //int bind(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
 
        s_addr.sin_family=AF_INET;//协议族
        s_addr.sin_port=htons(atoi(argv[2]));//返回网络字节序的值
        inet_aton(argv[1],&s_addr.sin_addr);//把字符串形式的IP转换为网络能识别的格式
 
        int nbind=bind(sfd,(struct sockaddr*)&s_addr,sizeof(struct sockaddr_in));
        if(nbind == -1)
        {
                perror("bind");
                exit(-1);
        }
        //3.lieten 监听
        // int listen(int sockfd, int backlog);
 
        int nlisten=listen(sfd,10);
        if(nlisten == -1)
        {
                perror("listen");
                exit(-1);
        }
        //4.accept 连接
        //int accept(int sockfd,struct sockaddr *addr,socklen_t *addrlen);
        int len=sizeof(struct sockaddr_in);
                while(1){
                        cfd=accept(sfd,(struct sockaddr*)&c_addr,&len);
                        if(cfd == -1)
                        {
                                perror("accept");
                                exit(-1);
                        }
                        printf("connect success:%s\n",inet_ntoa(s_addr.sin_addr));//打印连接的地址
                        if(fork() == 0){//一个子进程负责一条连接通道
                                while(1){
                                        //5.recv 接受数据
                                        // ssize_t recv(int sockfd, void *buf, size_t len, int flags);//与read功能类似
                                        //ssize_t read(int fd, void *buf, size_t count);
                                        memset(&msgs.cmd,'\0',sizeof(msgs.cmd));
                                        nread=read(cfd,&msgs,sizeof(msgs));
                                        if(nread == 0){//没有读到数据
                                                printf("client out!\n");
                                                exit(-1);
                                        }
                                        else if(nread > 0)//读到可用数据
                                        {
                                                msgs_Handler(msgs,cfd);//处理接受的数据指令
                                        }
                                }
                        }
                }
                return 0;
}

客户端代码 :

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <sys/msg.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <pthread.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <netinet/in.h>
#include <arpa/inet.h>
 
#define LS      0
#define PWD     1
#define GET     2
#define CD      3
 
#define IFGO    4
 
#define LLS     5
#define LCD     6
#define PUT     7
#define QUIT    8
#define DOFILE  9
 
struct msg
{
    int type;
    char cmd[1024];        //存放命令和文件数据
    char secondBuf[1024];   //存放文件内容
};
 
int get_cmd_type(char* cmd)//把字符串转换成整形数
{
        //char *strstr(const char *haystack, const char *needle);//搜索一个字符串在另一个字符串中的第一次出现
        if(strcmp(cmd,"ls")  == 0)        return LS;
        if(strcmp(cmd,"lls")  == 0)       return LLS;
        if(strcmp(cmd,"pwd")  == 0)       return PWD;
        if(strcmp(cmd,"quit") == 0)      return QUIT;
        //char *strstr(const char *haystack, const char *needle);//搜索一个字符串在另一个字符串中的第一次出现
        if(strstr(cmd,"get") != NULL)    return GET;
        if(strstr(cmd,"put") != NULL)     return PUT;
        if(strstr(cmd,"cd")  != NULL)      return CD;
        if(strstr(cmd,"lcd") != NULL)     return LCD;
        return -1;
}
 
char* getdir(char* cmd)
{
        char* fp;
        //char *strtok(char *s, char *delim)//分解字符串 str 为一组字符串,delim 为分隔符,返回值:分隔符匹配到的第一个子串
        fp=strtok(cmd,"|");
        fp=strtok(NULL,"|");
        return fp;
}
 
int cmd_Handler(struct msg msgs,int cfd)
{
        int ret;
        int fdfile;
        char* dir=NULL;
        //char buf[32];
 
        ret=get_cmd_type(msgs.cmd);//将字符串转换成整形数
        printf("ret:%d\n",ret);
        switch(ret)
        {
                case PWD:
                case LS:
                case CD:
                        write(cfd,&msgs,sizeof(msgs));
                        break;
 
                case GET:
                        write(cfd,&msgs,sizeof(msgs));
                        break;
 
                case PUT:
                        //strcpy(buf,msgs.cmd);
                        dir=getdir(msgs.cmd);
                        if(access(dir,F_OK) == -1)
                        {
                                printf("%s not exist\n",dir);
                        }
                        else
                        {
                                fdfile=open(dir,O_RDWR);
                                read(fdfile,msgs.secondBuf,sizeof(msgs.secondBuf));
 
                                write(cfd,&msgs,sizeof(msgs));
                                close(fdfile);
                        }
                        break;
 
                case LCD:
                        //printf("LCDsucess!\n");//调试信息
                        dir=getdir(msgs.cmd);
                        if(access(dir,F_OK) == -1)
                        {
                                printf("No this file!\n");
                        }
                        else
                        {
                                chdir(dir);
                        }
                        break;
 
                case LLS:
                        //printf("999999\n");
                         system("ls");
                         break;
 
                case QUIT:
                        //strcpy(msgs.cmd,"quit");
                        write(cfd,&msgs,sizeof(msgs));
                        close(cfd);
                        exit(-1);
                        break;
 
    }
                return ret;
 }
 
void handler_server_message(int cfd,struct msg msgs)
{
        int nread;
        int fd;
        struct msg msgget;
 
        nread=read(cfd,&msgget,sizeof(msgget));//读取服务端传来的数据
 
        if(nread == 0)
        {
                perror("server out!\n");;
                exit(-1);
        }
 
        else if(msgget.type == DOFILE)
        {
                char* p=getdir(msgs.cmd);
                fd= open(p,O_RDWR|O_CREAT,0600);
                write(fd,msgget.cmd,strlen(msgget.cmd));
                close(fd);
                putchar('>');
                fflush(stdout);
        }
        else
        {
                printf("------------------------\n");
                printf("\n%s\n",msgget.cmd);
                printf("------------------------\n");
 
                fflush(stdout);
                putchar('>');
        }
}
int main(int argc,char** argv)
{
 
        int cfd;
        int ret;
        struct msg msgs;
 
        struct sockaddr_in c_addr;
        memset(&c_addr,'\0',sizeof(c_addr));
 
        if(argc != 3)//判断传入参数是否有三个
        {
                printf("program error!\n");
                exit(-1);
        }
 
        //1.socket//创建套接字
        //int socket(int domain, int type, int protocol);
        cfd=socket(AF_INET,SOCK_STREAM,0);
        if(cfd == -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);//把字符串形式的IP转换为网络能识别的格式
 
        //2.connect 连接//客户连接主机
        //int connect(int sockfd, const struct sockaddr *addr,socklen_t addrlen);
        int nconnect=connect(cfd,(struct sockaddr*)&c_addr,sizeof(struct sockaddr_in));
        if(nconnect == -1)
        {
                perror("connect");
                exit(-1);
        }
 
        printf("connect......\n");
 
        for(;;){
                memset(msgs.cmd,0,sizeof(msgs.cmd));//初始化数组
 
                scanf("%s",msgs.cmd);//获取用于输入
 
                ret=cmd_Handler(msgs,cfd);//对输入信息进行处理,返回对应指令的值
 
                if(ret > IFGO)//过滤错误信息
                {
                        putchar('>');
                        fflush(stdout);
                        continue;
                }
 
                if(ret == -1)
                {
                        printf("command not\n");
                        printf(">");
                        fflush(stdout);
                        continue;
                }
 
                handler_server_message(cfd,msgs);//操作服务器传递过来的数据
        }
        return 0;
}

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

LEO-max

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值