项目(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 退出