User (No, Name, Password, G#) -- 候選鍵 No,外鍵 G#
Group (G#, GroupName, Demo) -- 主鍵 G#
ER 圖見原文圖片。
enum MSGTYPE { LOGIN, LOGINResponse, CHATTING, USERList, NOTICE };
class CMsg : public CObject {
public:
int m_eType; // 訊息類型
CString m_strMsg; // 內容,格式隨類型而異
CMsg(); virtual ~CMsg();
virtual void Serialize(CArchive& ar);
};
| m_eType | m_strMsg 內容 (以 | 分隔) |
|---|---|
| LOGIN | 暱稱|密碼 |
| LOGINResponse | GOOD|歡迎!(BOSS) 或 FAILED|驗證失敗! |
| CHATTING | 接收用戶|訊息內容 |
| USERList | 暱稱1|暱稱2|...|暱稱n|END |
| NOTICE | ALL|內容 或 發送者|內容 |
CString Decode(int n, CString strMsg) {
int pos; CString str;
for (int i=1; i<=n; i++) {
pos = strMsg.Find('|', 0);
if (pos < 0) str = strMsg;
else str = strMsg.Left(pos);
strMsg = strMsg.Right(strMsg.GetLength() - pos - 1);
}
return str;
}
void CMsg::Serialize(CArchive& ar) {
if (ar.IsStoring()) ar << m_strMsg << m_eType;
else ar >> m_strMsg >> m_eType;
}
int m_iPort;
CSocketListen* m_pSocket;
CSocketClient m_SocketClient[Max];
CArchive *m_pArOut, *m_pArIn;
CSocketFile* m_pSF;
CMsg msg;
void CSuperServerView::MyReceive(CSocketClient* pClient) {
m_pSF = new CSocketFile(pClient);
m_pArIn = new CArchive(m_pSF, CArchive::load);
msg.Serialize(*m_pArIn);
switch (msg.m_eType) {
case LOGIN:
// 驗證帳密,回覆 LOGINResponse,成功則 SendUserList()
break;
case CHATTING:
// 依目標暱稱尋找對應 Socket 轉發
break;
case NOTICE:
// 廣播給所有在線非發送者用戶
break;
}
}
void CSuperServerView::MyAccept() {
for (int i=0; iAccept(m_SocketClient[i]);
m_SocketClient[i].GetView(this);
break;
}
}
新增/刪除/修改/查詢帳號,使用 CDaoRecordset 的 AddNew/Delete/Edit/Update 方法。
// CSocketListen
void OnAccept(int nErrorCode) { m_pView->MyAccept(); CSocket::OnAccept(nErrorCode); }
// CSocketClient
void OnClose(int nErrorCode) { m_pView->MyClose(this); CSocket::OnClose(nErrorCode); }
void OnReceive(int nErrorCode) { m_pView->MyReceive(this); CSocket::OnReceive(nErrorCode); }
CMsg msg;
CMySocket* m_pSocket;
CArchive *m_pArOut, *m_pArIn;
CSocketFile* m_pSF;
void CClientDlg::OnLogin() {
// 建立 Socket、連線、送出 LOGIN 訊息
}
void CClientDlg::MyReceive() {
msg.Serialize(*m_pArIn);
switch (msg.m_eType) {
case LOGINResponse: // 處理登入結果、顯示介面
case USERList: // 解碼填入列表框
case CHATTING: // MessageBox 顯示
case NOTICE: // MessageBox 顯示
}
}
// CMySocket::OnReceive
void OnReceive(int nErrorCode) { m_pDlg->MyReceive(); CSocket::OnReceive(nErrorCode); }
伺服器主視窗、用戶端登入/主介面/收發訊息畫面見原文圖片。