版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
./用CSocket類實(shí)現(xiàn)的網(wǎng)絡(luò)聊天室一、服務(wù)器端應(yīng)用程序〔Ts.exe的實(shí)現(xiàn)步驟1、建立"基于對話框"類型的MFC項目,項目名稱Ts。按照向?qū)нM(jìn)行設(shè)置,當(dāng)打開"高級功能"設(shè)置頁面時,勾選"Windows套接字"選項,如圖所示,其他步驟采用默認(rèn)值即可。2、界面控件設(shè)計。在對話框資源編輯窗口中設(shè)計如圖所示界面,界面上控件的屬性按照下表設(shè)置。序號控件類型ID屬性值1IDC_STATICCaption監(jiān)聽端口號:2IDC_EDIT_PORT3IDC_BUTTON_LISTENCaption監(jiān)聽4IDOKCaption停止服務(wù)DisabledTrue5ID_LIST_MSGSortFalse6IDC_STATIC_NUMCaption聊天室在線人數(shù):03、打開"MFC類向?qū)?,按照下表設(shè)置控件在CTsDlg類中的成員變量,效果如圖所示;控件ID成員變量名稱類別變量類型IDC_STATIC_NUMm_strNumValueCStringIDC_EDIT_PORTm_nPortValueUINTIDC_BUTTON_LISTENm_btnListenControlCButtonIDOKm_btnCloseControlCButtonIDC_LIST_MSGm_listMsgControlCListBox4、選擇菜單"項目"->"添加類",添加一個"MFC類":CMsg,基類選擇CObject,如圖所示。為CMsg添加兩個成員變量: CStringm_strText;//字符串成員,消息文本
BOOLm_bClose; //退出聊天室標(biāo)識
接下來,在Msg.h文件中添加DECLARE_SERIAL宏,在Msg.cpp文件中添加IMPLEMENT_SERIAL宏;最后,使用MFC類向?qū)砑犹摵瘮?shù)Serialize<>,如圖所示。CMsg類的代碼如下://Msg.h#pragmaonce//CMsg命令目標(biāo)classCMsg:publicCObject{ DECLARE_SERIAL<CMsg>public: CMsg<>;virtual~CMsg<>;public: CStringm_strText;//字符串成員,消息文本 BOOLm_bClose; //退出聊天室標(biāo)識virtualvoidSerialize<CArchive&ar>;};//Msg.cpp:實(shí)o|ì現(xiàn)?文?件t#include"stdafx.h"#include"Ts.h"#include"Msg.h"http://CMsgIMPLEMENT_SERIAL<CMsg,CObject,0>CMsg::CMsg<>{}CMsg::~CMsg<>{}voidCMsg::Serialize<CArchive&ar>{if<ar.IsStoring<>> { //storingcode ar<<m_strText<<m_bClose; }else { //loadingcode ar>>m_strText>>m_bClose; }}5、從CSocket類派生兩個套接字類,一個名為CLSocket,專用于監(jiān)聽客戶機(jī)端的連接請求;另一個名為CCSocket,用于與客戶機(jī)建立連接并交換數(shù)據(jù)。操作步驟為:選擇菜單"項目"->"添加類",在彈出的對話框中選擇"MFC類"項,單擊"添加"按鈕;然后在彈出的"MFC添加類向?qū)?窗口中輸入類名,并選擇基類為CSocket,如圖所示。6、使用"MFC類向?qū)?為CLSocket類添加OnAccept事件處理函數(shù),操作如圖所示。7、使用"MFC類向?qū)?為CCSocket類添加OnReceive事件處理函數(shù),操作如下圖所示。8、分別為CLSocket和CCSocket類添加一個指向?qū)υ捒蝾惖闹羔樧兞浚?/p>
CTsDlg*m_pDlg;
為避免對話框類與套接字類交叉引用,在類的定義前添加
classCTsDlg;
修改CLSocket和CCSocket類的構(gòu)造函數(shù),添加一個CTsDlg*類型的參數(shù)。如圖所示。
在LSocket.cpp中添加頭文件的引用,并完成CLSocket類構(gòu)造函數(shù)的修改:#include"TsDlg.h"CLSocket::CLSocket<CTsDlg*pDlg>{this->m_pDlg=pDlg;}同樣,在CSocket.cpp中添加頭文件的引用,并完成CCSocket類構(gòu)造函數(shù)的修改:#include"TsDlg.h"CCSocket::CCSocket<CTsDlg*pDlg>{this->m_pDlg=pDlg;}9、為CCSocket類添加成員變量和成員函數(shù)的定義〔CSocket.h。
成員變量:
CSocketFile*m_pFile; //CSocketFile對象指針變量
CArchive*m_pArIn; //用于輸出的CArchive對象指針
CArchive*m_pArOut; //用于輸出的CArchive對象指針
成員函數(shù):
voidReceiveMsg<CMsg*pMsg>;//接收消息
voidSendMsg<CMsg*pMsg>; //發(fā)送消息
voidInitialize<>; //初始化
在CSocket.cpp中,實(shí)現(xiàn)這三個成員函數(shù),并修改CCSocket類的析構(gòu)函數(shù):voidCCSocket::Initialize<>{ m_pFile=newCSocketFile<this,TRUE>; m_pArIn=newCArchive<m_pFile,CArchive::load>; m_pArOut=newCArchive<m_pFile,CArchive::store>;}voidCCSocket::SendMsg<CMsg*pMsg>{ if<m_pArOut!=NULL> { pMsg->Serialize<*m_pArOut>; m_pArOut->Flush<>; }}voidCCSocket::ReceiveMsg<CMsg*pMsg>{ pMsg->Serialize<*m_pArIn>;}CCSocket::~CCSocket<>{ m_pDlg=NULL; if<m_pArOut!=NULL>{m_pArOut->Close<>; deletem_pArOut; m_pArOut=NULL;} if<m_pArIn!=NULL>{ m_pArIn->Close<>; deletem_pArIn; m_pArIn=NULL;} if<m_pFile!=NULL>{m_pFile->Close<>;deletem_pFile; m_pFile=NULL;}}10、在TsDlg.h文件〔CTsDlg類的定義文件中添加下面兩個文件的引用:#include"CSocket.h"#include"LSocket.h"并添加成員變量: CLSocket*m_pLSocket; //監(jiān)聽套接字指針 CPtrListm_connList; //連接列表和成員函數(shù)的聲明: voidbackClient<CMsg*pMsg>;//向聊天室所有客戶機(jī)轉(zhuǎn)發(fā)消息 voidOnReceive<CCSocket*pSocket>;//獲取客戶機(jī)消息 voidOnAccept<>;//接受連接請求在TsDlg.cpp中,實(shí)現(xiàn)這三個成員函數(shù):voidCTsDlg::OnAccept<>{ CCSocket*pSocket=newCCSocket<this>;if<m_pLSocket->Accept<*pSocket>> { pSocket->Initialize<>; m_connList.AddTail<pSocket>; CStringstrTemp; strTemp.Format<L"在線人數(shù):%d",m_connList.GetCount<>>; m_strNum=strTemp; UpdateData<FALSE>; }elsedeletepSocket;}voidCTsDlg::OnReceive<CCSocket*pSocket>{staticCMsgmsg;do { pSocket->ReceiveMsg<&msg>; m_listMsg.AddString<msg.m_strText>; backClient<&msg>;if<msg.m_bClose> { pSocket->Close<>; POSITIONpos,temp; CCSocket*pTemp;for<pos=m_connList.GetHeadPosition<>;pos!=NULL;> { temp=pos; pTemp=<CCSocket*>m_connList.GetNext<pos>;if<pTemp==pSocket> { m_connList.RemoveAt<temp>; CStringstrTemp; strTemp.Format<L"在線人數(shù):%d",m_connList.GetCount<>>; m_strNum=strTemp; UpdateData<FALSE>; } }deletepSocket;break; } }while<!pSocket->m_pArIn->IsBufferEmpty<>>;}voidCTsDlg::backClient<CMsg*pMsg>{ CCSocket*pSocket;for<POSITIONpos=m_connList.GetHeadPosition<>;pos!=NULL;> { pSocket=<CCSocket*>m_connList.GetNext<pos>; pSocket->SendMsg<pMsg>; }}11、完成CLSocket類的OnAccept<>函數(shù)的代碼〔第6步添加的虛函數(shù):voidCLSocket::OnAccept<intnErrorCode>{ CSocket::OnAccept<nErrorCode>;if<m_pDlg!=NULL>m_pDlg->OnAccept<>;}完成CCSocket類的OnAccept<>函數(shù)的代碼〔第7步添加的虛函數(shù):voidCCSocket::OnReceive<intnErrorCode>{ CSocket::OnReceive<nErrorCode>; m_pDlg->OnReceive<this>;}12、為對話框CTsDlg的"監(jiān)聽"和"停止服務(wù)"兩個按鈕添加消息響應(yīng)函數(shù)?!卜椒梢栽趯υ捒蛸Y源編輯窗口雙擊對應(yīng)按鈕,或使用類向?qū)oidCTsDlg::OnBnClickedButtonListen<>{//TODO:Addyourcontrolnotificationhandlercodehere UpdateData<TRUE>; m_pLSocket=newCLSocket<this>;if<!m_pLSocket->Create<m_nPort>> {deletem_pLSocket; m_pLSocket=NULL; AfxMessageBox<L"創(chuàng)建監(jiān)聽套接字錯誤">;return; }if<!m_pLSocket->Listen<>> {deletem_pLSocket; m_pLSocket=NULL; AfxMessageBox<L"啟動監(jiān)聽錯誤">;return; } GetDlgItem<IDC_EDIT_PORT>->EnableWindow<FALSE>; GetDlgItem<IDC_BUTTON_LISTEN>->EnableWindow<FALSE>; GetDlgItem<IDOK>->EnableWindow<TRUE>;}voidCTsDlg::OnBnClickedOk<>{//TODO:Addyourcontrolnotificationhandlercodehere CMsgmsg; msg.m_strText=L"服務(wù)器終止服務(wù)";deletem_pLSocket; m_pLSocket=NULL; CCSocket*pSocket;while<!m_connList.IsEmpty<>> { pSocket=<CCSocket*>m_connList.RemoveHead<>; pSocket->SendMsg<&msg>;deletepSocket; }while<m_listMsg.GetCount<>!=0> m_listMsg.DeleteString<0>; GetDlgItem<IDC_EDIT_PORT>->EnableWindow<TRUE>; GetDlgItem<IDC_BUTTON_LISTEN>->EnableWindow<TRUE>; GetDlgItem<IDOK>->EnableWindow<FALSE>;}13、最后,在CTsdlg類的OninitDialog<>函數(shù)中添加如下初始化代碼: m_nPort=8000; UpdateData<FALSE>; GetDlgItem<IDOK>->EnableWindow<FALSE>;效果如下:二、客戶端應(yīng)用程序〔Tc.exe的實(shí)現(xiàn)步驟1、建立"基于對話框"類型的MFC項目,項目名稱Tc。按照向?qū)нM(jìn)行設(shè)置,當(dāng)打開"高級功能"設(shè)置頁面時,勾選"Windows套接字"選項,如圖所示,其他步驟采用默認(rèn)值即可。2、界面控件設(shè)計。在對話框資源編輯窗口中設(shè)計如圖所示界面,界面上控件的屬性按照下表設(shè)置。序號控件類型ID屬性值1IDC_EDIT_CNAME2IDC_EDIT_SNAME3IDC_EDIT_PORT4IDC_EDIT_MSG5ID_LIST_MSGSortFalse6IDC_BUTTON_CLOSECaption退出7IDC_BUTTON_CONNCaption連接8IDOKCaption發(fā)送9IDC_STATICCaption客戶名:10IDC_STATICCaption服務(wù)器名:11IDC_STATICCaption端口:12IDC_STATICCaption消息:3、打開"MFC類向?qū)?,按照下表設(shè)置控件在CTsDlg類中的成員變量,效果如圖所示;控件ID成員變量名稱類別變量類型IDC_EDIT_CNAMEm_strCNameValueCStringIDC_EDIT_SNAMEm_strSNameValueCStringIDC_EDIT_PORTm_nPortValueUINTIDC_EDIT_MSGm_strMsgValueCStringIDC_BUTTON_CONNm_btnConnControlCButtonIDOKm_SendControlCButtonID_BUTTON_CLOSEm_btnCloseControlCButtonIDC_LIST_MSGm_listMsgControlCListBox4、創(chuàng)建CMsg類。方法同服務(wù)器端應(yīng)用程序〔Ts.exe步驟4。 也可以直接將服務(wù)器端應(yīng)用程序的CMsg類添加到當(dāng)前工程中,方法為: 1首先將Msg.h和Msg.cpp兩個文件復(fù)制到當(dāng)前工程目錄下; 2然后選擇菜單"項目"->"添加現(xiàn)有項",在彈出的對話框中選中這兩個文件,單擊"添加"按鈕,如圖所示; 3這時在類視圖中會出現(xiàn)CMsg類,如圖所示。 4打開CMsg類的實(shí)現(xiàn)文件〔Msg.cpp,將其中的頭文件引用:#include"Ts.h"改為:#include"Tc.h"5、從CSocket類派生一個套接字類CCSocket,用于與客戶機(jī)建立連接并交換數(shù)據(jù)。如圖所示:6、使用類向?qū)?為CCSocket類添加OnReceive事件處理函數(shù),如圖所示。8、為CCSocket類添加一個指向?qū)υ捒蝾惖闹羔樧兞浚?/p>
CTcDlg*m_pDlg;
為避免對話框類與套接字類交叉引用,在類的定義前添加
classCTcDlg;
修改CCSocket類的構(gòu)造函數(shù),添加一個CTcDlg*類型的參數(shù)。如圖所示。
在CSocket.cpp中添加頭文件的引用,并完成CCSocket類構(gòu)造函數(shù)的修改:#include"TcDlg.h"CCSocket::CCSocket<CTcDlg*pDlg>{ m_pDlg=pDlg;}9、在TcDlg.h文件〔CTsDlg類的定義文件中添加下面的頭文件引用:#include"CSocket.h"并添加成員變量: CCSocket*m_pSocket; //套接字對象指針 CSocketFile*m_pFile;//CSoketFile對象指針 CArchive*m_pArchiveIn;//用于輸入的CArchive對象 CArchive*m_pArchiveOut;//用于輸出的CArchive對象和成員函數(shù)的聲明: voidOnReceive<>;//接收信息 voidReceiveMsg<>;//接收服務(wù)器發(fā)送來的消息 voidSendMsg<CString&strText,boolst>;//向服務(wù)器發(fā)送消息在TcDlg.cpp中,添加對Msg.h文件的引用和實(shí)現(xiàn)這三個成員函數(shù):#include"Msg.h"voidCTcDlg::OnReceive<>{do{ ReceiveMsg<>;if<m_pSocket==NULL>return; }while<!m_pArchiveIn->IsBufferEmpty<>>;}voidCTcDlg::ReceiveMsg<>{ CMsgmsg; TRY { msg.Serialize<*m_pArchiveIn>; m_listMsg.AddString<msg.m_strText>; } CATCH<CFileException,e> { CStringstrTemp; strTemp=L"服¤t務(wù)?器??重?置?連¢?接¨?!ê?連¢?接¨?關(guān)?閉à?"; m_listMsg.AddString<strTemp>; msg.m_bClose=TRUE; m_pArchiveOut->Abort<>;deletem_pArchiveIn; m_pArchiveIn=NULL;deletem_pArchiveOut; m_pArchiveOut=NULL;deletem_pFile; m_pFile=NULL;deletem_pSocket; m_pSocket=NULL; } END_CATCH}voidCTcDlg::SendMsg<CString&strText,boolst>{if<m_pArchiveOut!=NULL> { CMsgmsg; msg.m_strText=strText; msg.m_bClose=st; msg.Serialize<*m_pArchiveOut>; m_pArchiveOut->Flush<>; }}10、為對話框CTcDlg的"退出"、"連接"和"發(fā)送"三個按鈕添加消息響應(yīng)函數(shù)?!卜椒梢栽趯υ捒蛸Y源編輯窗口雙擊對應(yīng)按鈕,或使用類向?qū)oidCTcDlg::OnBnClickedButtonConn<>{//TODO:Addyourcontrolnotificationhandlercodehere UpdateData<TRUE>; m_pSocket=newCCSocket<this>;if<!m_pSocket->Create<>> {deletem_pSocket; m_pSocket=NULL; AfxMessageBox<L"套接字創(chuàng)建錯誤">;return; }if<!m_pSocket->Connect<m_strSName,m_nPort>> {deletem_pSocket; m_pSocket=NULL; AfxMessageBox<L"無法連接到服務(wù)器">;return; } m_pFile=newCSocketFile<m_pSocket>; m_pArchiveIn=newCArchive<m_pFile,CArchive::load>; m_pArchiveOut=newCArchive<m_pFile,CArchive::store>; UpdateData<TRUE>; CStringstrTemp; strTemp=m_strCName+L":進(jìn)入聊天室"; SendMsg<strTemp,FALSE>; GetDlgItem<IDC_EDIT_MSG>->EnableWindow<TRUE>; GetDlgItem<IDOK>->EnableWindow<TRUE>; GetDlgItem<IDC_BUTTON_CLOSE>->EnableWindow<TRUE>; GetDlgItem<IDC_EDIT_CNAME>->EnableWindow<FALSE>; GetDlgItem<IDC_EDIT_SNAME>->EnableWindow<FALSE>; GetDlgItem<IDC_EDIT_PORT>->EnableWindow<FALSE>; GetDlgItem<IDC_BUTTON_CONN>->EnableWindow<FALSE>;}voidCTcDlg::OnBnClickedButtonClose<>{//TODO:Addyourcontrolnotificationhandlercodehere CStringstrTemp; strTemp=m_strCName+L"離開聊天室"; SendMsg<strTemp,TRUE>;deletem_pArchiveOut; m_pArchiveOut=NULL;deletem_pArchiveIn; m_pArchiveIn=NULL;deletem_pFile; m_pFile=NULL; m_pSocket->Close<>;deletem_pSocket; m_pSocket=NULL;while<m_listMsg.GetCount<>!=0> { m_listMsg.DeleteString<0>; } GetDlgItem<IDC_EDIT_MSG>->EnableWindow<FALSE>; GetDlgItem<IDOK>->EnableWindow<FALSE>; GetDlgItem<IDC_BUTTON_CLOSE>->EnableWindow<FALSE>; GetDlgItem<IDC_EDIT_CNAME>->EnableWindow<TRUE>; GetDlgItem<IDC_EDIT_SNAME>->EnableWindow<TRUE>; GetDlgItem<IDC_EDIT_PORT>->EnableWindow<TRUE>; GetDlgItem<IDC_BUTTON_CONN>->EnableWindow<TRUE>;}11、打開類向?qū)?為TcDlg類
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 二零二五年度建筑分公司承包經(jīng)營合作協(xié)議細(xì)則3篇
- 二零二五年度個體工商戶合伙經(jīng)營借款合同2篇
- 解讀《紅樓夢》模板
- 寒假最后一課安全教育
- 二零二五年CFG樁施工合同履約績效評價合同協(xié)議2篇
- 2025年度版權(quán)許可協(xié)議針對影視作品播放權(quán)
- 種植之路模板
- 2025年度消防安全設(shè)施改造與責(zé)任合同2篇
- 二零二五年度商業(yè)辦公空間按季度租金及配套設(shè)施租賃合同3篇
- 2023-2024學(xué)年仁愛版七上期末考試英語(試題)
- 無人機(jī)表演服務(wù)合同
- 2024年醫(yī)院培訓(xùn)計劃
- 呼吸內(nèi)科臨床診療指南及操作規(guī)范
- 學(xué)生管理教育課件
- 物業(yè)經(jīng)理轉(zhuǎn)正述職
- 貿(mào)易崗位招聘面試題及回答建議(某大型國企)2025年
- 世界職業(yè)院校技能大賽高職組“關(guān)務(wù)實(shí)務(wù)組”賽項參考試題及答案
- 高中歷史教師資格考試面試試題及解答參考(2024年)
- 銀行貸款房產(chǎn)抵押合同樣本
- 北師大版(2024新版)生物七年級上冊期末考點(diǎn)復(fù)習(xí)提綱
評論
0/150
提交評論