Linux C/C++項目:虛擬文件服務器(功能匹配百度網盤)

github地址:https://github.com/Worthy-Wang/NetDisk


FTP文件服務器設計思路:

1.整體架構採用線程池結合epoll監聽

客戶端通過sockfd與服務器通信,服務器通過sockfd進行連接新的客戶端,用accept到的newfd與客戶端進行通信;
主線程負責向子線程分配任務,子線程負責處理任務並於客戶端通信;
簡單命令主線程直接執行,puts 和 gets 命令交給子線程執行。

2.文件系統採用虛擬文件目錄設計,將所有的文件存放在一個公共目錄中,自己只能看到自己的文件,並創建好一個存放文件信息的數據庫(此處數據庫採用MYSQL)

FileId | Dir | FileName | FileSize |FileType | MD5 |User |
FileId : 文件ID, 主鍵, 自增型
Dir : 所在目錄,0則表示根目錄
FileName : 文件名稱,可以相同,區分靠FileId
FileSize : 文件大小(B顯示)
FileType : f 代表文件類型,d代表文件夾類型
MD5 : 文件的MD5值,用來判斷文件的內容是否相同
User :文件的所屬對象

命令實現:

1.cd 進入對應目錄
2.ls 列出相應目錄文件
3.puts 將本地文件上傳至服務器
4.gets 文件名 下載服務器文件到本地
5.mkdir 增加文件夾
6.rm 刪除服務器上文件
7.quit 退出
8.其他命令不響應

功能實現:

1.用戶登陸與密碼驗證
類似/etc/shadow文件下的鹽值加密,使用crypt函數進行加密,將用戶賬號,密碼以及加密後的數據存放在數據庫中;
鹽值salt(隨機生成)的8個字符,密碼匹配方式是服務器根據客戶端的用戶名找到其Salt,並將Salt發送回客戶端,客戶端進行crypt加密後再發送給服務器進行匹配,其中需要注意客戶端是沒有權限訪問數據庫的
User | Password | Salt | Cipher

2.記錄日誌信息:包括客戶端的請求信息,客戶端連接時間,客戶端的操作記錄以及操作時間,並將信息都存放在數據庫中;
User | Operation | time

3.文件的斷點續傳:客戶端gets過程中如果斷開,再次gets時,從斷點開始傳輸
具體實現:客戶端如果有要接收的文件file並已經下載了1000字節,則向服務器發送 gets file 1000, 服務器直接從偏移1000字節的位置開始傳送,客戶端也偏移1000字節開始接收

4.使用token令牌
token的介紹:https://www.jianshu.com/p/24825a2683e6

5.連接上的客戶端如果30s沒有相應,那麼關閉描述符
https://mp.weixin.qq.com/s?__biz=MjM5ODYxMDA5OQ==&mid=2651959957&idx=1&sn=a82bb7e8203b20b2a0cb5fc95b7936a5&chksm=bd2d07498a5a8e5f9f8e7b5aeaa5bd8585a0ee4bf470956e7fd0a2b36d132eb46553265f4eaf&mpshare=1&scene=23&srcid=0718Qlp4AVKnZq1E1f144pE6#rd
此處採用輪詢掃描法,設置Map<string,int> //<用戶名,上一次發送包的時間>
設置一個timer,每秒都輪詢Map中的元素,並將時間差大於30s的客戶端連接斷開

6.多點下載(選做)

數據庫創建(只需進入數據庫執行一次即可):

##########################################

創建數據庫 Netdisk

##########################################
CREATE DATABASE Netdisk;
use Netdisk

##########################################

創建表 Virtual_Dir

##########################################
CREATE TABLE Virtual_Dir
(
FileId int NOT NULL AUTO_INCREMENT,
Dir int NOT NULL,
FileName varchar(10) NOT NULL,
FileSize BIGINT NULL,
FileType char(1) NOT NULL,
MD5 varchar(50) NULL,
User varchar(10) NOT NULL,
PRIMARY KEY(FileId)
) ENGINE=InnoDB;

INSERT INTO Virtual_Dir(Dir, FileName, FileSize, FileType, MD5, User)
VALUES(0, ‘file5’, 512, ‘f’, ‘md5’, ‘wwx’);

##########################################

創建表 Shadow

##########################################
CREATE TABLE Shadow
(
User varchar(10) NOT NULL,
Password varchar(18) NOT NULL,
Salt char(8) NOT NULL,
Cipher text NOT NULL,
PRIMARY KEY(User)
) ENGINE=InnoDB;

INSERT INTO Shadow
VALUES(‘wwx’, ‘123’, ‘xxxxxxxx’, ‘xxx…xxx’);

##########################################

創建表 Log

##########################################
CREATE TABLE Log
(
Id int NOT NULL AUTO_INCREMENT,
User varchar(100) NOT NULL,
Operation varchar(100) NOT NULL,
time varchar(100) NOT NULL,
PRIMARY KEY(Id)
) ENGINE=InnoDB;

INSERT INTO Log (User, Operation, time)
VALUES();

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章