又到了每天寫日報的時間了。
總結昨日
日報
還是先記錄前一天的日報情況。
1號 | https://blog.csdn.net/qq_43762191/article/details/106856827 |
---|---|
2號 | https://blog.csdn.net/qq_45792305/article/details/106870557 |
3號 | https://blog.csdn.net/blackcamouflage/article/details/106865699 |
4號 | https://blog.csdn.net/luyaozhima/article/details/106863462 |
5號 | https://blog.csdn.net/jxy0219/article/details/106865207 |
6號 | 2 |
8號 | https://blog.csdn.net/qq_42151344/article/details/106865571 |
9號 | https://blog.csdn.net/qq_46485161/article/details/106866715 |
進度
昨天大家都走出了第一步,客戶端陸陸續續都在畫界面,服務器方面我也初步建設好數據庫和解壓包兩個模塊,其他人也在抓緊學習,呈現出明顯的分化,努力的人越努力。
項目週期調整
昨天還做出了一個調整,鑑於大家壓力都比較大,所以決定將之後的一個項目日分爲兩天,天天開會大家會覺得沒什麼好講的了。相應的改動便是將項目週期由12個工作日改爲10個項目日,實際時間由原先的16天延長爲20天。
此外,會議主要討論瞭解壓包模塊應該如何進行,接下來會看到我設計的類圖。
解壓包模塊設計
解壓包模塊代碼(可編譯,未測試)
//packet_base.h
#pragma once
#include<string>
#define MAX_PACKET_LENTH 1024
//設置包最大長度爲1024,
// ! ! ! 暫時不考慮會太小的情況 ! ! !
typedef struct packet_header_st
{
int fd;//用於前後端通信即目標客戶端fd(服務器用到)
int funcId; // 功能號
//登錄包0x01,註冊包0x02,找回密碼0x03,修改密碼0x04
//客戶端獲取文件列表0x11,上傳文件0x12,下載文件0x13,共享文件0x14,除獲取列表外各種文件業務應答0x15
//心跳0x21
int optid; // 操作碼:請求0x00 和 應答0x01
int usrlenth;// 包體的長度
int packet_seq; //包序號
int packet_sum; //包總數
char srcAddr[6]; //預留
char dstAddr[6]; //預留
int syn; // 判斷包頭是否正確 0x04
}packet_header_t;
/************接入層數據包尾************/
typedef struct packet_tali_st//包尾,用來驗證數據包的完整性
{
int pack_tail;//設置爲0x05
}packet_tali_t;
/************數據包報文整體************/
typedef struct packet_all_st
{
packet_header_t Head;
char* body;
packet_tali_st tail;
}packet_all_st;
class PacketBase
{
protected:
int m_Size;
int Body_Size; //包體大小
packet_header_t Head;
packet_tali_t Tail;
char* Body;
char m_Data[MAX_PACKET_LENTH];
public:
PacketBase();
~PacketBase();
bool pack();
bool unpack();
char* getBody();
packet_header_t* getHead();
packet_tali_t* getTail();
char* getData();
int getSize();
void setSize(int size);
void setBodySize(int bodysize);
PacketBase& operator =(const PacketBase& packet);
};
//packet_base.cpp
#include "PacketBase.h"
#include<iostream>
PacketBase::PacketBase() {
memset(&Head, 0, sizeof(Head));
memset(&Tail, 0, sizeof(Tail));
}
PacketBase::~PacketBase() {
delete Body; //如果要用智能指針的話,先測一下大小
}
bool PacketBase::pack()
{
Body = new char[Body_Size];
memcpy(m_Data, &this->Head, sizeof(packet_header_t));
memcpy(m_Data + sizeof(packet_header_t), this->Body, sizeof(Body)); //這個Body長度在封包的時候定
memcpy(m_Data + sizeof(packet_header_t) + sizeof(Body), &this->Tail, sizeof(packet_tali_t));
return true;
}
bool PacketBase::unpack()
{
if (Body_Size <= 0) { //如果數據不足
std::cout << "數據包破損" << std::endl;
return false;
}
Body = new char[Body_Size]; //防止越界可以在這裏下手
memcpy(&this->Head, m_Data, sizeof(packet_header_t)); //先將包頭讀出
memcpy(Body, m_Data + sizeof(packet_header_t), sizeof(Body));
memcpy(&this->Tail, m_Data + sizeof(packet_header_t) + sizeof(Body), sizeof(packet_tali_t));
return true;
}
char* PacketBase::getBody() {
return Body;
}
packet_header_t* PacketBase::getHead() {
return &Head;
}
packet_tali_t* PacketBase::getTail() {
return &Tail;
}
char* PacketBase::getData() {
return m_Data;
}
int PacketBase::getSize() {
return m_Size;
}
//這個給解包用
void PacketBase::setSize(int size) {
this->m_Size = size;
this->Body_Size = size - sizeof(packet_header_t) - sizeof(packet_tali_t);
}
//這個給封包用
void PacketBase::setBodySize(int bodysize) {
this->Body_Size = bodysize;
this->m_Size = Body_Size + sizeof(packet_header_t) + sizeof(packet_tali_t);
}
//這個不知道幹嘛用,歷史遺留
PacketBase& PacketBase::operator =(const PacketBase& packet)
{
memset(m_Data, 0, MAX_PACKET_LENTH);
if (m_Size != packet.m_Size)
{
m_Size = packet.m_Size;
}
memcpy(m_Data, packet.m_Data, packet.m_Size);
return *this;
}
//自定義協議包
#pragma once
/************業務層數據包體************/
//客戶端登錄請求包
typedef struct login
{
int id;
int pwd; //密碼
}Login_t;
//登錄應答包
typedef struct res_login_st
{
int login_ret; //登錄結果: 1-登錄成功,0-登錄失敗
int dir_id; //初始文件列表id
}res_login_t;
//客戶端註冊請求包
typedef struct Register
{
int id; //賬號
char tel[12]; //11位手機號
int pwd; //密碼
}Register_t;
//註冊應答包
typedef struct res_register_st
{
int register_ret; //註冊結果: 0-註冊成功,1-註冊失敗
}res_register_t;
//客戶端修改密碼請求包
typedef struct Change_PWD
{
int id; //賬號
int pwd; //密碼
}c_pwd_t;
//改密碼應答包
typedef struct res_changepwd_st
{
int change_ret; //改密碼結果: 0-改密碼成功,1-改密碼失敗
}res_cpwd_t;
//找回密碼請求包
typedef struct findpwd
{
int id;
int tel[12];
}F_Pwd_t;
//找回密碼應答包
typedef struct res_findpwd_st
{
int find_ret; //找回結果: 0-找回成功,1-找回失敗
int pwd; //密碼
}res_fpwd_t;
//銷戶請求包
typedef struct deluser
{
int id;
int pwd;
}D_user_t;
/**********************************文件相關****************************************/
//上傳文件請求包
typedef struct UpFile
{
int user_id;
int dir_id;
int mode; //文件權限位
int pwd;
char* file_name;
}UpFile_t;
//下載文件請求包
typedef struct Download_File
{
int user_id; //用戶ID
int pwd;
char* file_name; //文件id
}Download_t;
//文件分享
typedef struct Cmode
{
int id;
int pwd;
int mode;
int yaoqingma; //邀請碼
char* file_name;
}C_mode_t;
//新建目錄
typedef struct AddFileList
{
int id;
int pwd;
int father_dir; //掛載在哪一級目錄底下
char* dirname;
}A_filelist_t;
//修改文件目錄
typedef struct CFileList
{
int id;
int pwd;
int old_dir;
int new_dir;
char* file_name;
}C_filelist_t;
//刪除文件
typedef struct delfile
{
int id;
int pwd;
char* file_name;
}D_file_t;
//刪除目錄
typedef struct dellist
{
int id;
int pwd;
int dir_id;
} D_list_t;
//文件、目錄總應答
typedef struct res_fl
{
int stata; //0成1敗
}res_fl_t;
//文件列表請求包
typedef struct File_List
{
int user_id; //用戶ID
int pwd;
int dir_id; //目錄id
}FileList_t;
//文件列表應答包
typedef struct Res_VideoList
{
char V[800];
}res_filelist_t;
//心跳處理
typedef struct Heart
{
int heart; //佔位
}res_heart_t;
//packet_command.h
#pragma once
#include "PacketBase.h"
#include "Packet1.h"
class PacketCommand1:protected PacketBase
{
public:
PacketCommand1();
bool replyLogin(int state,int dir_id, int fd);
bool replyRegist(int state, int fd);
bool replyCpwd(int state, int fd);
bool replyFpwd(int state,int pwd, int fd);
bool replyFL(int state, int fd);
bool replyFileList(char* filelist, int fd);
};
//packet_command.cpp
#include "PacketCommand1.h"
PacketCommand1::PacketCommand1():PacketBase(){
}
bool PacketCommand1::replyLogin(int state, int dir_id,int fd) {
Head.funcId = 0x01;
Head.optid = 0x01;
Head.fd = fd;
Head.usrlenth = sizeof(Body); //誰開的包誰封回去,所以大小是相對靜止了
Head.syn = 0x04;
res_login_t* body = (res_login_t*)Body;
body->login_ret = state;
body->dir_id = dir_id;
Tail.pack_tail = 0x05;
return this->pack();
}
bool PacketCommand1::replyRegist(int state, int fd) {
Head.funcId = 0x02;
Head.optid = 0x01;
Head.fd = fd;
Head.usrlenth = sizeof(Body);
Head.syn = 0x04;
res_register_t* body = (res_register_t*)Body;
body->register_ret = state;
Tail.pack_tail = 0x05;
return this->pack();
}
bool PacketCommand1::replyFpwd(int state, int pwd, int fd) {
Head.funcId = 0x03;
Head.optid = 0x01;
Head.fd = fd;
Head.usrlenth = sizeof(Body);
Head.syn = 0x04;
res_fpwd_t* body = (res_fpwd_t*)Body;
body->find_ret = state;
body->pwd = pwd;
Tail.pack_tail = 0x05;
return this->pack();
}
bool PacketCommand1::replyCpwd(int state, int fd) {
Head.funcId = 0x04;
Head.optid = 0x01;
Head.fd = fd;
Head.usrlenth = sizeof(Body);
Head.syn = 0x04;
res_cpwd_t* body = (res_cpwd_t*)Body;
body->change_ret = state;
Tail.pack_tail = 0x05;
return this->pack();
}
bool PacketCommand1::replyFL(int state, int fd) {
Head.funcId = 0x15;
Head.optid = 0x01;
Head.fd = fd;
Head.usrlenth = sizeof(Body);
Head.syn = 0x04;
res_fl_t* body = (res_fl_t*)Body;
body->stata = state;
Tail.pack_tail = 0x05;
return this->pack();
}
bool PacketCommand1::replyFileList(char* filelist, int fd) {
Head.funcId = 0x11;
Head.optid = 0x01;
Head.fd = fd;
Head.usrlenth = sizeof(Body);
Head.syn = 0x04;
res_filelist_t* body = (res_filelist_t*)Body;
memcpy(body->V,filelist,sizeof(filelist));
Tail.pack_tail = 0x05;
return this->pack();
}
數據庫模塊修改
對數據庫模塊測試之後,做了幾個修改,這裏主要列幾個
//DB_base.cpp
//獲取查詢記錄中第n個數據(數據需有效)
int DB_base::ireturn_serch(char* sql, int n)
{
char* errMsg;
char** dbResult;
int nRow = 0, nColumn = 0;
int rc;
int result;
rc = sqlite3_get_table(db, sql, &dbResult, &nRow, &nColumn, &errMsg);
if (nRow == 0 || dbResult[nColumn + n - 1] == NULL) {
return 0; //如果沒有數據,返回0
}
if (rc == SQLITE_OK && n <= nColumn)
{
result = atoi(dbResult[nColumn + n - 1]);
sqlite3_free_table(dbResult);
return result;
}
else
{
cout<<nColumn<<endl<<nRow<<endl;
cout << "ireturn_serch" << endl;
return NULL;
}
}
//返回多個結果,以ret參數形式返回
void DB_base::ret_any(char* sql,char* ret) {
char* errMsg;
char** dbResult;
int nRow = 0, nColumn = 0;
int rc;
int result;
rc = sqlite3_get_table(db, sql, &dbResult, &nRow, &nColumn, &errMsg);
if (rc == SQLITE_OK){
for (int count = nColumn; count < (nRow * (nColumn + 1)); count++) {
strcat(ret,dbResult[count]);
}
}
else
cout << "ret_any" << endl;
}
//DB_command.cpp
//獲取文件列表下所有目錄、文件
void DB_command::file_list(int user_id, int pwd, int dir_id, char* ret){
if (login(user_id, pwd)) {
char* sql = new char[120];
memset(sql,0,120);
sprintf(sql, "select file_name from FileMsg where owner_id = %d and dir_id = %d", user_id, dir_id);
My_DB->ret_any(sql, ret);
sprintf(sql, "select dir_name from DirMsg where grade = %d",dir_id);
My_DB->ret_any(sql, ret);
delete sql;
}
else
cout << "can't get file list" << endl;
}
今日計劃
原計劃
測試代碼:解壓包模塊與epoll模型
實際計劃
由於應邀出席某個畢業班的評審嘉賓,所以下午就沒時間了。所以今天將epoll模塊也設計好,儘量爭取把代碼也敲了。
這兩個模塊的測試只能留待明天了,因爲測試是未知數,誰也不知道會測出什麼問題來。
一定是可以實現的!!!