小度网盘(简单实现)


项目(linux下小度网盘系统)
1) 添加到简历中
2) 能讲清楚,功能、用到的技术、实现方法(面试官会问)

要求:
1)  实现类似百度网盘
2)  注册
3)  登录
4)  显示我的文件列表
5)  下载我的文件
6)  上传文件
7)  历史记录

问题:
1   用udp 还是 tcp实现  :   
    tcp 实现, 在Internet网上实现,  支持多客户端
    分为 服务器  和  客户端
    服务器 用 多线程并发服务器

2   用户信息   历史信息  用什么保存(数据库还是文件)
    数据库存 历史信息和 用户信息
    用户信息表有哪些字段?    用户ID   密码    用户名
    历史信息表          ?    用户ID   时间    操作内容 (get hello.c     list     put hello.c)
    
3   文件列表如何存取
    服务器
        当有一个客户端注册时,服务器新建一个和用户名同名的  文件夹, 专门用来存此用户的文件
        当用户list时,服务器扫描目录,将文件名 分别 传给 客户端
    客户端
        注册时,传入用户名,密码
        list时,给服务器  发 type = 1
                     
4   功能有哪些 :  
    注册、登录、获取list、上传文件、下载文件、获得 历史记录
    扩充功能:  删除文件、分享(链接 + 提取密码)、vip用户下载加速
 
5   用到哪些技术 :  
    socket通信、文件I/O 、多线程并发服务器、目录操作、sqlite3数据库

6   怎么实现
    设计一个公共结构体    
    struct net_info
    {
        int type;    //1 注册 2 登录  3 list  4 get  5 put  6 exit
        char username[20];
        char password[20];
        char file_name[100];
        char info[500];
        int len;
    };
开始做
1) 实现数据库的设计
    用户信息表 (userid(varchar),   passwd(varchar),  username(varchar))
    历史信息   (userid(varchar),   history(varchar), his_time(varchar))

##########create_table.sql##############################
drop table if exists user_info;
create table user_info(userid varchar, passwd varchar, username varchar);
drop table if exists his_info;
create table his_info(userid varchar, history varchar, his_time varchar);
########################################################

sqlite3 netdisk.db < create_table.sql

2) 用 服务器和客户端模型 改

******1 register    2 login    3 list   4 get file    5   put file   6 exit*****

代码框架
client.c/
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
struct net_info
{
    int type;    //1 注册 2 登录  3 list  4 get  5 put  6 exit
    char username[20];
    char password[20];
    char file_name[100];
    char info[500];
    int len;
};
int fd = 0;
void *recv_fun(void *p)
{
    struct net_info s;
    while(1)
    {
        if(recv(fd, &s, sizeof(s), 0) <= 0)
            break;
        if(s.type == 1)
        {
            printf("%s\n", s.info);
        }
    }
}
int main(int argc, char *argv[])
{
    pthread_t id;
    fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in youaddr;    
    youaddr.sin_family = AF_INET;
    youaddr.sin_port = htons(atoi(argv[2]));
    youaddr.sin_addr.s_addr = inet_addr(argv[1]);
    connect(fd, (struct sockaddr *)&youaddr, sizeof(youaddr));
    pthread_create(&id, NULL, recv_fun, NULL);
    while(1)
    {    
        struct net_info s;
        printf("******1 register    2 login    3 list   4 get file    5   put file   6 exit*****\n");
        scanf("%d", &s.type);
        if(s.type == 1)
        {
            printf("please input userid:");
            scanf("%s", s.username);
            printf("please input passwd:");
            scanf("%s", s.password);    //有bug  1) 密码确认  2) 密码隐藏
            send(fd, &s, sizeof(s), 0);    
        }
    }
    close(fd);
}

///server.c
#include <stdio.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <pthread.h>
#include <string.h>
#include <sqlite3.h>
sqlite3 *p_db;    //数据库的指针
struct net_info
{
    int type;    //1 注册 2 登录  3 list  4 get  5 put  6 exit
    char username[20];
    char password[20];
    char file_name[100];
    char info[500];
    int len;
};

void user_register(struct net_info *p, int fd)    //注册
{//1.  检查是否注册过(看数据库是否有此条记录  用select)
 //2. 如果没注册,填进数据库,新建文件夹
    char  *errmsg,**resultp;
    int  nrow,  ncolumn;
    char sql[100] = { 0 };
    sprintf(sql, "select * from user_info where userid = '%s'", p->username);
    sqlite3_get_table(p_db, sql,  &resultp,  &nrow, &ncolumn,  &errmsg);
    if(nrow > 0)    //用户已存在
    {
        strcpy(p->info, "register: user exist");
        send(fd, p, sizeof(struct net_info), 0);
    }
    else
    {
        sprintf(sql, "insert into user_info values('%s', '%s', '%s')", p->username, p->password, p->username);
        sqlite3_exec(p_db, sql, NULL, NULL,&errmsg);
        strcpy(p->info, "register: success");
        send(fd, p, sizeof(struct net_info), 0);
    }
}
void *recv_fun(void *p)    //recv_fun 需要保存newfd
{
    int fd = *(int *)p;
    struct net_info s;
    while(1)
    {
        char buf[100] = { 0 };
        if(recv(fd, &s, sizeof(s), 0) <= 0)    //newfd 代表连接的客户端
            break;
        printf("recv type is %d\n", s.type);
        if(s.type == 1)    //注册
        {    
            user_register(&s, fd);
        }
    }
}
int main()
{
    int fd = socket(AF_INET, SOCK_STREAM, 0);
    struct sockaddr_in myaddr;
    myaddr.sin_family = AF_INET;
    myaddr.sin_port = htons(8888);
    myaddr.sin_addr.s_addr = htonl(INADDR_ANY);    //INADDR_ANY 得到当前计算机的ip地址
    int ret = bind(fd, (struct sockaddr *)&myaddr, sizeof(myaddr));
    listen(fd, 5);
    sqlite3_open("netdisk.db", &p_db);  //如果数据库不存在,就创建
    while(1)
    {
        pthread_t id;
        int newfd = accept(fd, NULL, NULL);    //等待客户端连接
        printf("new client %d\n", newfd);
        pthread_create(&id, NULL, recv_fun, &newfd);
    }
    close(fd);
}

gcc hello.c -o server -lpthread -lsqlite3
gcc hello.c -o client -lpthread -lsqlite3

./server

./client 127.0.0.1 8888

继续完成
1 登录
2 文件列表list
3 下载文件
4 上传文件
5 历史记录
6 退出

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值