初步計划,這個聊天平台不要UI,但支持功能有:
- 創建賬號密碼
- 建立聊天室(對應命令'$create')
- 加入房間(對應命令'$enter')
- 退出房間(對應命令'$exit')
- 有在線時長屬性,下線后上線不會消失(在線時長保存在文件中)
- 支持私聊,大廳聊天,房間聊天三種方式(私聊對應命令'$private')
- 可以看到房間列表,在房間里面可以看到房間的成員列表(對應命令'$list')
- 在房間中,每過半小時服務器會發布4個1-10的數字,進行21點的小游戲,表達式最接近21點者獲勝,相同結果則取最快者(輸入答案對應命令'$game')
開始動手設計
報文傳輸使用TCP,因為TCP發送會等待緩沖區滿或者超時才發包(nagle算法),所以要考慮粘包(當然也可以通過設置TCP的TCP_NODELAY選項避免這一項)
報文類型(type):注冊、創建聊天室、進入聊天室、退出聊天室、發送給聊天室的報文、私聊的報文、21點游戲的報文
服務器需要保存的文件:所有個人賬號及其信息(密碼,在線總時長)
服務器數據結構:在線個人賬號的字典(socketfd,房間號、登陸時間、標記是否已經參加游戲)、房間號字典(房間密碼,房間人數,對應的成員socketfd,游戲信息(題目,目前最佳答案,目前獲勝者))
服務器:創建事件列表,由接收報文觸發事件組成,另起一個線程作為定時器,到了整點和半點向所有房間發送21點游戲題目
客戶端:監聽接收報文,另起線程監聽控制台輸入
列表負責監聽socket,如果是服務器socketfd觸發調用accept,就將新的socketfd加入輸入事件列表,等待對端端報文;如果是連接的socketfd觸發則recv報文。對於接收的報文處理有以下幾種:
- 注冊報文(type:1, user:??????, password:******):
- 遍歷賬號文件,每行表示一個賬號信息,看這個user是否已經存在,如果存在則進行步驟2,如果不存在則進行步驟3;
- 回復報文(type:11, user:??????, errorcode:1)給客戶端;
- 將新的賬號密碼信息加入到賬號文件末尾一行,如果添加信息失敗,進行步驟4,如果成功進行步驟5;
- 回復報文(type:11, user:??????, errorcode:2)給客戶端;
- 回復報文(type:11, user:??????, errorcode:0)給客戶端。
- 創建聊天室報文(type:2, user:??????, room:??????, password:******):
- 是否存在該房間號,如果存在則進行步驟2,如果不存在則進行步驟3;
- 回復報文(type:12, room:??????, errorcode:1)給客戶端;
- 將新的賬號密碼等信息加入到聊天室賬號字典,進行步驟5;
- 回復報文(type:12, room:??????, errorcode:0)給客戶端。
- 進入聊天室報文(type:3, user:??????, room:??????, password:******):
- 是否存在該房間號,如果存在則進行步驟2,如果不存在則進行步驟3;
- 核對密碼是否匹配,如果匹配進行步驟4,不匹配進行步驟6;
- 回復報文(type:13, room:??????, errorcode:1);
- 將文件中的該房間人數+1,進行步驟5;
- 將房間號加入到報文user對應信息,進行步驟7;
- 回復報文(type:13, room:??????, errorcode:2);
- 回復報文(type:13, room:??????, errorcode:0)。
- 退出聊天室報文(type:4, user:??????):
- 找到user對應的聊天室賬號;
- 將user信息中的房間號重置為空,聊天室賬號信息成員人數-1,若人數為0,進行步驟3,若人數不為0,進入步驟4;
- 刪除該聊天室信息,進行步驟5;
- 回復報文(type:14, room:??????, errorcode:0)。
- 發送給聊天室的報文(type:5, user:??????, room:??????, content:"......"):
- 根據房間號,查看對應的個人賬號,對其轉發2;
- 發送(type:15, user:??????, room:??????, content:"......")。
- 私聊的報文(type:6, user:??????, target:??????, content:"......"):
- 該user是否在線,如果不在線,進行步驟2,如果存在進行步驟3;
- 回復報文(type:16, user:??????, target:??????);
- 轉發報文(type:16, user:??????, target:??????, content:"......")。
- 登陸報文(type:7, user:??????, password:??????):
- 遍歷賬號文件,查看是否存在該賬號,若不存在,則進行步驟3,若存在則進行步驟2;
- 核對密碼,如果密碼錯誤,則進行步驟4,若正確,進行步驟5;
- 回復報文(type:17, errorcode:1);
- 回復報文(type:17, errorcode:2);
- 將賬號信息加到在線字典里並回復報文(type:17, errorcode:0)。
- 21點小游戲題目報文(type:8, room:??????, num:[????])
- 21點小游戲答案報文(type:18, user:??????, room:??????, ans:??):
- 根據ans內容保存最佳答案以及其提供者
- 15秒后發送排名第一的user給房間各成員(type:10, room:??????, user:??????),若沒有成員提供答案則發送(type:10, room:??????, user:'')。
詳情見代碼以及注釋
