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;
}

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/zouchengzhi1021/article/details/113668089