linux网络——ftp云盘

  • Post author:
  • Post category:linux




1、功能



1.1服务端

1.接收客户端指令,实现如下的操作:

ls,rm,cd,pwd

上传和下载文件操作(get,put)

断开连接quit



1.2客户端

1.给服务器发送指令,实现相关操作

ls,rm,cd,pwd,get,put

2.客户端自身指令

lls,lrm,lcd,lpwd

3.退出程序指令quit



2、相关API



2.1初始化变量memset

void *memset(void *s, int c, size_t n);
/*用法例子*/
struct Mcc buf;
memset(&buf,'\0',sizeof(buf));
printf("%ld\n",sizeof(buf));
printf("set:%d\n",buf.set);
printf("type:%d\n",buf.type);
printf("cmd:%s\n",buf.cmd);
printf("data:%s\n",buf.data);
printf("%ld\n",sizeof(struct Mcc));
return 0;
/*输出结果
1160
set:0
type:0
cmd:
data:
1160
*/

功能:初始化赋值

参数1:任意类型变量,可以是结构体

参数2:赋的初值,常用0或者’\0’

参数3:长度,sizeof可以是变量也可以是数据类型



2.2判断文件是否存在access

int access(const char *pathname, int mode);

返回值:不存在返回-1

参数1:文件名字

参数2:这里用F_OK

R_OK 只判断是否有读权限

W_OK 只判断是否有写权限

X_OK 判断是否有执行权限

F_OK 只判断是否存在



2.3执行系统命令popen

FILE *popen(const char *command, const char *type);

int pclose(FILE *stream);

/*用法例子*/
struct Mcc buf;
memset(&buf,'\0',sizeof(buf));
FILE *f = popen("ls","r");
fread(buf.data,1024,1,f);
printf("open:%s",buf.data);
pclose(f);
/*输出结果
open:a.out
client
client.c
cs.c
ser
ser.h
server.c
*/

功能:执行shell可以获取输出结果,用fread读取结果,可以直接printf输出,也可以写入文件中。屏幕上不会直接打印出来

参数1:命令

参数2:r或w,一般要r



2.4改变当前目录chdir

int chdir(const char *path);

参数:指向目录的指针



2.5字符串分割strtok

char *strtok(char *str, const char *delim);
/*用法例子*/
char a[128]="xiao wei !!!";
//char *a = "xiao wei !!!";
char *p;
printf("a = %s\n",a);

p = strtok(a," ");
printf("p1 = %s\n",p);
printf("a = %s\n",a);

p = strtok(NULL," ");
printf("p2 = %s\n",p);
printf("a = %s\n",a);

p = strtok(NULL," ");
printf("p3 = %s\n",p);
printf("a = %s\n",a);

p = strtok(NULL," ")
printf("p4 = %s\n",p);
printf("a = %s\n",a);
return 0;

/*输出结果
a = xiao wei !!!
p1 = xiao
a = xiao
p2 = wei
a = xiao
p3 = !!!
a = xiao
p4 = (null)
a = xiao
*/

用法:

第一次调用参数1为字符串str(只能是数组a[],不能是指针类型char*a)

第二次参数1为NULL

原理:

第一次调用把字符串中分割符替换成’\0’,返回字符串地址

第二次跳过字符串的第一个\0,返回\0后面的字符串地址

最终原字符串已经被破坏,输出字符串只会输出第一个返回的字符串

参数1:要分割的字符串

参数2:分割符



2.6字符串比较strncmp

int strcmp(const char *s1, const char *s2);

int strncmp(const char *s1, const char *s2, size_t n);
/*例子*/
if(!strncmp("ls",buf,2))                return LS;

返回值:一样返回0,不一样非0

参数1:比较字符串1

参数2:比较字符串2

参数3:比较前几个是否一样


注:为什么不用strcmp,因为strcmp有时候会出错



3、实现思路


服务器


1.创建socket,等待客户端连接

2.有连接fork一个进程,服务器继续等待连接

3.fork的进程read等待信息,做出相应命令

4.read到quit结束进程


客户端


1.socket连接服务器

2.连接成功fork进程,父进程wait等待,子进程gets输入

3.子进程gets输入后传命令到服务器

4.gets到quit退出进程


上传,下载补充


1.做个char* p指针

2.用sleek计算出文件大小

3.malloc给p指针分配内存

4.把内容读到p

5.给服务器/客户端发2次内容,个数和文件内存

6.服务器/客户端malloc分配内存,接收文件内容,然后放到新创建文件



4、代码展示


头文件

#define LS 0
#define LLS 1

#define PWD 2
#define CD 3
#define RM 5

#define GET 6
#define PUT 7

#define LPWD 8
#define LCD 9
#define LRM 10

#define QUIT 120

struct Mcc
{
        int set;
        int type;
        char cmd[128];
        char data[1024];
};


服务器

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "ser.h"
#include <sys/stat.h>
#include <fcntl.h>

void serv_client(int c_fd)
{
        int set;
        int fd;
        struct Mcc buf;
        char *p;
        while(1)
        {
                memset(&buf,0,sizeof(buf));
                read(c_fd,&buf,sizeof(buf));
                printf("cmd:%s\n",buf.cmd);
                switch(buf.set)
                {
                        case QUIT:
                                exit(0);
                        case GET:
                                if(access(buf.cmd,F_OK) == -1)
                                {
                                        printf("type:%d\n",buf.type);
                                        strcpy(buf.data,"NO This file!!!");
                                        write(c_fd,&buf,sizeof(buf));
                                }
                                else
                                {
                                        fd = open(buf.cmd,O_RDWR);
                                        read(fd,buf.data,1024);
                                        write(c_fd,&buf,sizeof(buf));
                                        close(fd);
                                }
                                break;
                        case PUT:
                                fd = open(buf.cmd,O_RDWR|O_CREAT,0600);
                                write(fd,buf.data,1024);
                                close(fd);
                                break;
                        case PWD:
                        case LS:
                        {
                                FILE *f = popen(buf.cmd,"r");
                                fread(buf.data,1024,1,f);
                                write(c_fd,&buf,sizeof(buf));
                                pclose(f);
                                break;
                        }
                        case RM:
                                system(buf.cmd);
                                strcpy(buf.data,"success......\n");
                                write(c_fd,&buf,sizeof(buf));
                                break;
                        case CD:
                                chdir(buf.cmd);
                                strcpy(buf.data,"success......\n");
                                write(c_fd,&buf,sizeof(buf));

                                break;
                        case 100:
                                printf("error,Reenter!!!\n");
                                break;
                }
        }
}
int main(int argc,char **argv)
{
        if(argc != 3)
        {
                printf("usage: command listen_port\n");
                exit(-1);
        }
        int jieshou;
        int fid;
        int s_fd;
        int c_fd;
        struct sockaddr_in addr;
        struct sockaddr_in c_addr;
        memset(&c_addr,0,sizeof(struct sockaddr_in));
        memset(&addr,0,sizeof(struct sockaddr_in));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1],&addr.sin_addr);
        s_fd = socket(AF_INET,SOCK_STREAM,0);
        if(s_fd < 0)
        {
                perror("socket");
                exit(-1);
        }
        if(bind(s_fd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) < 0)
        {
                perror("bind");
                exit(-1);
        }
        if(listen(s_fd,10) < 0)
        {
                perror("listen");
                exit(-1);
        }
        jieshou = sizeof(struct sockaddr_in);
        while(1)
        {
                c_fd = accept(s_fd,(struct sockaddr *)&c_addr,&jieshou);
                if(c_fd < 0)
                {
                        perror("accept");
                        exit(-1);
                }
                else
                {
                        printf("client IP:%s\n",inet_ntoa(c_addr.sin_addr));
                }
                fid = fork();
                if(fid < 0)
                {
                        perror("fork error!");
                        exit(-1);
                }
                if(fid == 0)
                {
                        serv_client(c_fd);
                }
                close(c_fd);
        }
        return 0;
}


客户端

#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>          /* See NOTES */
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <unistd.h>
#include "ser.h"
char *S_tok(char *a)
{
        char *p;
        p = strtok(a," ");
        p = strtok(NULL," ");
        return p;
}
int get_cmd_type(char *buf)
{
        if(!strncmp("ls",buf,2))                return LS;
        if(!strncmp("lls",buf,3))               return LLS;
        if(!strncmp("quit",buf,4))              return QUIT;
        if(!strncmp("pwd",buf,3))               return PWD;
        if(!strncmp("lpwd",buf,4))              return LPWD;
        if(!strncmp("cd",buf,2))                return CD;
        if(!strncmp("lcd",buf,3))               return LCD;
        if(!strncmp("rm",buf,2))                return RM;
        if(!strncmp("lrm",buf,3))               return LRM;
        if(!strncmp("get",buf,3))               return GET;
        if(!strncmp("put",buf,3))               return PUT;
        return 100;
}
void serv_client(int c_fd)
{
        int fd;
        struct Mcc buf;

        char *p;
        printf(">>ls,cd,rm,pwd,lls,lcd,lrm,lpwd,quit,get,put<<\n");
        while(1)
        {
                printf("------------------------------------------------\n");
                memset(&buf,0,sizeof(buf));
                printf(">");
                gets(buf.cmd);

                buf.set = get_cmd_type(buf.cmd);
                switch(buf.set)
                {
                        case QUIT:
                                write(c_fd,&buf,sizeof(buf));
                                exit(0);
                        case PWD:
                        case LS:
                                write(c_fd,&buf,sizeof(buf));
                                read(c_fd,&buf,sizeof(buf));
                                printf("%s",buf.data);
                                break;
                        case CD:
                                p = S_tok(buf.cmd);
                                strcpy(buf.cmd,p);
                                write(c_fd,&buf,sizeof(buf));
                                read(c_fd,&buf,sizeof(buf));
                                printf("%s",buf.data);
                                break;
                        case RM:
                                write(c_fd,&buf,sizeof(buf));
                                read(c_fd,&buf,sizeof(buf));
                                printf("%s",buf.data);
                                break;
                        case GET:
                                p = S_tok(buf.cmd);
                                strcpy(buf.cmd,p);
                                write(c_fd,&buf,sizeof(buf));
                                read(c_fd,&buf,sizeof(buf));
                                if(buf.type != -1)
                                {
                                        fd = open(buf.cmd,O_RDWR|O_CREAT,0600);
                                        write(fd,buf.data,1024);
                                        close(fd);
                                }
                                else
                                {
                                        printf("%s\n",buf.data);
                                }
                                break;
                        case PUT:
                                p = S_tok(buf.cmd);
                                strcpy(buf.cmd,p);
                                if(access(buf.cmd,F_OK) == -1)
                                {
                                        printf("NO This file!!!\n");
                                }
                                else
                                {
                                        fd = open(buf.cmd,O_RDWR);
                                        read(fd,buf.data,1024);
                                        write(c_fd,&buf,sizeof(buf));
                                        close(fd);
                                }
                                break;
                        case LPWD:
                        case LLS:
                        case LRM:
                                p = buf.cmd;
                                p++;
                                system(p);
                                break;
                        case LCD:
                                p = S_tok(buf.cmd);
                                strcpy(buf.cmd,p);
                                chdir(buf.cmd);
                                printf("success......\n");
                                break;
                        case 100:
                                printf("error reenter!!!\n");
                                break;
                }
        }
}
int main(int argc,char **argv)
{
        if(argc != 3)
        {
                printf("usage: command listen_port\n");
                exit(-1);
        }
        int fid;
        int s_fd;
        struct sockaddr_in addr;
        memset(&addr,0,sizeof(struct sockaddr_in));
        addr.sin_family = AF_INET;
        addr.sin_port = htons(atoi(argv[2]));
        inet_aton(argv[1],&addr.sin_addr);
        s_fd = socket(AF_INET,SOCK_STREAM,0);
        if(s_fd < 0)
        {
                perror("socket");
                exit(-1);
        }
        if(connect(s_fd,(struct sockaddr *)&addr,sizeof(struct sockaddr_in)) == -1)
        {
                perror("connect");
                exit(-1);
        }
        printf("client......\n");
        fid = fork();
        if(fid < 0)
        {
                perror("fork error!");
                exit(-1);
        }
        if(fid == 0)
        {
                serv_client(s_fd);
                exit(0);
        }
        wait(NULL);
        close(s_fd);
        return 0;
}


师承上官可编程 —— 陈立臣



版权声明:本文为m0_51247005原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。