一. 調(diào)整目錄結(jié)構(gòu) 為了方便編譯,現(xiàn)在我們將前面文章的代碼結(jié)構(gòu)做如下調(diào)整。
root@ubuntu:/mnt/hgfs/code/chat#?tree?. . ├──?chat_client │???├──?include │???├──?Makefile │???├──?obj │???│???└──?Makefile │???└──?src │???????├──?client.c │???????└──?Makefile ├──?chat.h ├──?chat_server │???├──?bin │???│???└──?server │???├──?data │???├──?include │???├──?Makefile │???├──?obj │???│???└──?server.o │???└──?src │???????├──?Makefile │???????└──?server.c └──?gcc.sh10 ?directories,?15 ?files最終增加了數(shù)據(jù)的文件目錄如下:
peng@ubuntu:/mnt/hgfs/code/chat-sql ite$?tree?. . ├──?chat_client │???├──?include │???├──?Makefile │???├──?obj │???│???└──?Makefile │???└──?src │???????├──?client.c │???????└──?Makefile ├──?chat.h ├──?chat_server │???├──?data │???├──?include │???│???└──?data.h │???├──?Makefile │???├──?obj │???│???└──?Makefile │???└──?src │???????├──?data.c │???????├──?Makefile │???????└──?server.c ├──?clean.sh ├──?gcc.sh ├──?user.db └──?解壓密碼.txt 9?directories,?17?filesclean.sh 用于清除臨時文件gcc.sh 用于編譯整個工程服務(wù)端代碼放置到chat_server目錄下;客戶端代碼放置到chat_client目錄下;
數(shù)據(jù)庫 相關(guān)代碼放在chat_server/data下。chat.h是所有客戶端和服務(wù)器都會用到的頭文件,所以放置在根目錄下。后續(xù)增加功能后,新增的頭文件和C文件分別添加到對應(yīng)工程目錄的include和src目錄下即可。
二、 設(shè)計數(shù)據(jù)庫表 我們之前維護(hù)的所有客戶端的信息是用一個全局?jǐn)?shù)組,并且沒有保存功能,現(xiàn)在我們要把所有客戶端的信息全部保存到數(shù)據(jù)庫中。數(shù)據(jù)庫存儲的目錄
chat_server/data數(shù)據(jù)庫名:
user.db存儲用戶信息的表名:
user表user格式如下:
名稱 屬性 說明 name TEXT PRIMARY KEY 用戶名,不能重復(fù) passwd TEXT NOT NULL 密碼 fd INT NOT NULL 套接字描述符:-1表示不在線,>0表示在線 regist INT NOT NULL 用戶名是否注冊:-1沒有注冊,1注冊
三、 主要功能操作的語句及函數(shù) 數(shù)據(jù)庫操作最重要的就是語句,下面講解針對不同的功能對應(yīng)的實現(xiàn)語句
1 創(chuàng)建表user CREATE?TABLE?IF?NOT?EXISTS?user(name?TEXT?PRIMARY?KEY??NOT?NULL,passwd?TEXT?NOT?NULL,fd?INT?NOT?NULL,regist?INT??NOT?NULL);2 增加一個用戶 客戶端發(fā)送注冊請求后,服務(wù)器端注冊用戶信息到數(shù)據(jù)庫中數(shù)據(jù)庫操作語句如下:
insert?into?user?values('一口Linux' ,?'123456' ,-1,?1)功能函數(shù)如下:
int?db_add_user(char?name[],char?passwd[])功能: 增加一個用戶,執(zhí)行該函數(shù)前需要先判斷該用戶名是否存在 參數(shù): name:用戶名 passwd:密碼 返回值: -1:失敗 1:成功3 判斷用戶是否在線 客戶端發(fā)送登陸命令后,服務(wù)器通過該函數(shù)判斷該用戶是否已經(jīng)登陸成功數(shù)據(jù)庫操作語句如下:
select?fd?from?user?where ?name='一口Linux' 功能函數(shù)如下:
int?db_user_if_online(char?*name,char?*passwd)功能: 判斷用戶是否在線,該函數(shù)主要根據(jù)fd的值來判斷用戶是否在線 參數(shù): name:用戶名 passwd:密碼?? 返回值: 1:在線 -1:不在線 -2:用戶不存在4 判斷某個用戶名是否注冊 用戶發(fā)送注冊命令,服務(wù)器需要判斷該用戶名是否已經(jīng)被注冊過數(shù)據(jù)庫操作語句如下:
select?regist?from?user?where ?name='一口Linux' 功能函數(shù)如下:
int?db_user_if_reg(char?*name)功能: 判斷某個用戶名是否注冊過 參數(shù): name:用戶名 返回值: ?1:注冊過 -1:沒有注冊過5 判斷用戶名密碼是否正確 用戶發(fā)送登陸命令,需要判斷用戶名密碼是否正確數(shù)據(jù)庫操作語句如下:
select?*?from?user?where ?name='一口Linux' ?and?passwd='123456' 功能函數(shù)如下:
int?db_user_pwd_corrct(char?*name,char*?passwd)功能: 判斷客戶端發(fā)送的用戶名密碼是否正確 參數(shù): name:用戶名 passwd:密碼 返回值: ?1:正確 -1:用戶名或者密碼不正確6 用戶上線、下線 用戶登陸成功后,或者發(fā)送下線申請,或者異常掉線,需要更新數(shù)據(jù)庫的狀態(tài)。數(shù)據(jù)庫操作語句如下:
UPDATE??user?set ?fd=-1?where ?name='一口Linux' fd的值是套接字描述符,下線設(shè)置為-1,上線設(shè)置為對應(yīng)的>0的值功能函數(shù)如下:
int?db_user_on_off(int?fd,char?*name,unsigned?int?on_off)?功能: 更新數(shù)據(jù)庫中用戶的fd字段 參數(shù): fd:套接字描述符 name:用戶名 on_off:上線還是下線 返回值: ?1:正確 -1:失敗7. 顯示在線用戶 用戶發(fā)送顯示在線用戶命令后,服務(wù)器從數(shù)據(jù)庫當(dāng)中查找所有在線用戶,并將姓名循環(huán)發(fā)送給客戶端
int ?db_list_online_user (int ?fd) 四、運行結(jié)果 編譯 ./gcc .sh 1.服務(wù)器啟動 ./server?9999端口號設(shè)定為9999
2. 客戶端注冊 客戶端啟動
./client?127.0.0.1?9999選擇1 ?注冊,輸入用戶名密碼即可。
3. 用戶登錄 輸入選項2,輸入剛才注冊的用戶名密碼,如果不一致會提示錯誤登錄成功:
4. 注冊登錄其他幾個用戶 注冊并登錄新的用戶111、222、333
5. 公聊 選擇選項3,即進(jìn)入公聊, 用戶yikou向所有用戶說:hello!可見所有用戶均收到信息。
6. 私聊 用戶yikou向用戶111發(fā)送信息:由下圖可知,只有用戶111收到該信息,其他用戶均沒有收到信息。
7. 顯示在線用戶 8. 查看最終數(shù)據(jù)庫信息 五、代碼說明 為方便讀者學(xué)習(xí)增加數(shù)據(jù)庫和去掉數(shù)據(jù)之間的差別,用git維護(hù)版本。
切換到?jīng)]有數(shù)據(jù)庫的版本,執(zhí)行下面命令即可。
git?reset?--hard??597330ae0a183c9db8f68b7c9f60df94f8965778要切回有數(shù)據(jù)庫的版本執(zhí)行下面的命令:
git?reset?--hard?10bfbfaf2d09ae895313273c960ecfd84663f9fd使用
數(shù)據(jù)庫 后,數(shù)據(jù)的存儲管理更加方便,數(shù)據(jù)類型更易于擴充, 邏輯關(guān)系也更加清晰。版權(quán)申明:內(nèi)容來源網(wǎng)絡(luò),版權(quán)歸原創(chuàng)者所有。除非無法確認(rèn),我們都會標(biāo)明作者及出處,如有侵權(quán)煩請告知,我們會立即刪除并表示歉意。謝謝!