版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進行舉報或認領(lǐng)
文檔簡介
基于Csocket的聊天程序?qū)嶒炈氖褂肅Socket類的網(wǎng)絡(luò)通信基礎(chǔ)知識CSocket類是CAsyncSocket類的派生類,它提供了對通過CArchive對象使用套接字工作的更高級抽象。CSocket類的使用比CAsyncSocket類更加容易,它繼承了CAsyncSocket類的許多封裝了API的成員函數(shù),并且管理了通信的大多數(shù)方面,這使用戶從原來不得不使用原始API或者AsyncSocket類的繁雜工作巾解脫出來。更加重要的是CSocket類提供了對于同步操作CArchive對象十分重要的阻塞功能,且CSocket通過與類CSocketFile和CArchive一起來管理對數(shù)據(jù)的發(fā)送和接收,使收發(fā)數(shù)據(jù)的操作變得簡單明了CSocket類是CAsyncSocket類的派生類,它對WinsockAPI進行進一步封裝,因此它的成員函數(shù)比CAsyncSocket要少得多,不難掌握。(1)CSocket和Create這兩個函數(shù)與CAsyncSocket類的同名成員函數(shù)的作用和用法相似。(2)IsBlocking該函數(shù)用來確定套接字當(dāng)前是否有正在執(zhí)行的阻塞調(diào)用,其原型為:BOOLIsBlocking();如果套接字處于阻塞狀態(tài),則返回非0值,否則返回0。(3)FromHandle該函數(shù)用于從給定的SOCKET句柄中得到相應(yīng)的CSocket對象指針,其原型為:staticCSocket*PASCALFromHandle(SOCKEThSocket);其中,參數(shù)hSocket是給定的SOCKET句柄。如果函數(shù)調(diào)用成功,則返回CSocket對象指針,如果返回NULL,則該句柄沒有與socket對象相連。(4)Attach該函數(shù)用于將SOCKET句柄與CSocket對象相連,其原型為:BOOLAttach(SOCKEThSocket):其中,hSocket用于知道欲與CSocket對象相連的SOCKET句柄。如果函數(shù)調(diào)用成功則返回非0值,否則返回0。(5)CancelBlockingCall該函數(shù)用于取消正存進行的阻塞調(diào)用,其原型為:voidCanceIBlockingCall();通過調(diào)用該函數(shù),原始的阻塞調(diào)用將立即被中止,并返回錯誤碼WSAEINTR。注意:如果阻塞是由Connect調(diào)用引起的,則雖然WindowsSockets將立即中止阻塞調(diào)用,但是除非連接完成或超時,否則套接字資源可能都不會被釋放,而且除非1被取消的調(diào)用為Accept,否則該函數(shù)都將使套接字處于不確定的狀態(tài)。(6)OnMessagePending重載該函數(shù)可以在Windows中尋找并響應(yīng)特定的消息,其原型為:virtualBOOLOnMessagePending():如果該消息被處理,則返回非0值,否則返回0。共同使用CSocket與CArchive對象是最簡單的套接字編程模型,其中CArchive對象將幫助程序員處理許多以前必須使用API或CAsyncSocket類來處理的通信問題,大大減少了編程的工作量。圖1值得注意的是,盡管CSocketFile類是CFile的派生類,但它并不支持CFile的一些成員函數(shù),例如Seek、GetLengh、SetLengh、LockRange、UnlockRange以及GetPosition等函數(shù),這還是比較容易理解的,因為CSocketFile是從相關(guān)的CSocket對象中讀出或?qū)懭胱止?jié)序列,與文件無關(guān),諸如Seek或GetPosition等函數(shù)并無意義。為了禁止CSocketFile所不支持的CFile成員函數(shù)在CSocketFile類中被重載,在執(zhí)行重載這些函數(shù)時,就會觸發(fā)一個CNotSupportedException異常。此外,CSocketFile也能單獨使用(不與CArchive對象共I同使用)。默認情況下,CSocketFile的構(gòu)造函數(shù)的bArchiveCompatible參數(shù)為TRUE,這指定了文件對象與歸檔一起使用。要使文件對象不與歸檔一起使用,只需將bArchiveCompatible設(shè)置為FALSE即可。不過,當(dāng)CSocketFile與歸檔對象一起使用時,它具有更好的性能,并減少了“死鎖”的危險。CSocket編程模型如圖2所示。注意:CArchive對象只能單向傳遞數(shù)據(jù):載入(接收)或存儲(發(fā)送)。在某些情況下,用戶越須使用兩個CArchive對象,一個進行數(shù)據(jù)發(fā)送,而另一個進行數(shù)據(jù)2接收。并且CArchive類特別為CSocket類提供了IsBufferEmpty成員函數(shù),如果緩沖區(qū)包含多個數(shù)據(jù)消息,例如,需要循環(huán)直到所有的數(shù)據(jù)都被讀出,并且緩沖區(qū)被清空。否則,下一個將接收數(shù)據(jù)的通告可能被無限延遲。使用IsBufferEmpty函數(shù),可以確定接收到了所有數(shù)據(jù)。此外,CSocket類也和CAsyncSocket-樣提供了一些重載函數(shù),包括:OnReceive、OnSend、OnAccept、OnConnect和OnClose并且CSocket類還提供了一個高級的重載函數(shù)OnMessagePending。MFC在套接寧響應(yīng)Windows消息時調(diào)用該函數(shù)??梢灾剌dOnMessagePending函數(shù)以從Windows尋找特定的消息并響應(yīng)它們。它的默認版本是,當(dāng)?shù)却枞{(diào)用完成時,檢查消息隊列并尋找WM_PAINT消息,它發(fā)送重繪消息以便提高顯示質(zhì)量。因此假如要用到這些重載函數(shù)的話,一般需要從CSocket類派生自己的Socket類方能重載這些函數(shù)。本實驗采用CSocket編程模型建立一個聊天程序的簡單實例。使用vc++6建立一個基于對話框的工程,建立工程時注意選上“Windows套接字”復(fù)選框。圖2編程模型編程步驟:3一、服務(wù)器端應(yīng)用程序設(shè)計(工程名稱SocSvr)1.1、界面及各控件屬性界面如下:4各控件屬性如下控件類型控件IDCaption屬性控件變量變量類型列表框IDC_LST_Logm_lst_logCListBox編輯框IDC_EDT_SenMsgm_edt_senMsgCEdit按鈕IDC_BTN_Sendm_btn_sendCButton列表框控件IDC_LST_Log的屬性“sort”值為false,屬性“HorizontalScroll”值為true。按鈕IDC_BTN_Send屬性Disable值為true。1.2、定義CSocket類的派生類CSocListen和CSocRecv從CSocket編程模型知道,服務(wù)器端需要兩種套接字,一個用來偵聽連接請求,一個用來與請求連接的套接字建立連接。因此,為程序添加兩個CSocket派生類:SSocListen和CSocRecv,它們與對話框類密切配合,共同完成程序所要求實現(xiàn)的功能。在vc集成環(huán)境左側(cè)的工程管理欄中,切換到“classview”頁,對準“SocSvrClasses”點右鍵,在彈出的菜單中點擊“newclass”,彈出“newclass”對話框。在此對話框的“Classtype”組合框中選擇“MFCClass”,在“Baseclass”組合框中選擇“CSocket”,然后再在“Name”文本框中填入類的名稱“CSocListen”,點擊“OK”按鈕。這樣,一個CSocket類的派生類“CSocListen”就創(chuàng)建好了。用同樣的方法創(chuàng)建CSocket類的另一個派生類“CSocRecv”。創(chuàng)建過程的對話框如下圖所示。51.3、建立套接字與對話框類的關(guān)聯(lián)在程序中,對話框類要用到套接字類,而套接字類在響應(yīng)某些消息,如在函數(shù)OnAccept、OnReceive中進行處理時,也要改變對話框的某些控件狀態(tài),以反映給用戶這些事情的發(fā)生。這里存在著兩個類相互使用的情況,把套接字類對象定義成對話框類的成員變量,同時在套接字類中也把對話框類定義為成員變量。如何實現(xiàn)這樣的用法呢,在對話框類實現(xiàn)文件(cpp文件)中加入套接字頭文件的聲明,然后在套接字類實現(xiàn)文件(cpp文件)中加入對話框類頭文件的聲明,然后在對話框類的頭文件里把套接字的指針變量定義為對話框的成員變量,再在套接字類的頭文件里把對話框的指針變量定義為對該套接字的成員變量。具體做法應(yīng)該如下:首先,在SocSvrDlg.h文件中加入套接字類頭文件的聲明,語句#pragmaonce的后面加入如下語句:classCSocListen;//聲明偵聽類classCSocRecv;//聲明接收客戶端消息類然后在該文件中為CSocSvrDlg類增加兩個公有成員變量,語句如下:CSocListen*m_pCSocListen;//定義一個偵聽類的指針6CSocRecv*m_pCSocRecv;//定義一個接收客戶端消息類的指針再在SocSvrDlg.cpp文件中把兩個套接字類的頭文件包含進來:#include"SocListen.h"http://偵聽類,包含進來#include"SocRecv.h"http://接收客戶端消息類,包含進來這樣在對話框類中就可以使用套接字類了。接下來在套接字類中加入對話框類信息。首先,在SocListen.h文件的開頭,語句#pragmaonce的后面加入如下語句:classCSocSvrDlg;//聲明對話框類然后,在該文件中為CSocListen類添加一個公有成員變量和一個構(gòu)造函數(shù):CSocListen(CSocSvrDlg*pDlgSocSvr);CSocSvrDlg*m_pDlgSocSvr;接著在SocListen.cpp文件中添加新的構(gòu)造函數(shù)的實現(xiàn),并添加一條關(guān)于SocSvrDlg.h文件的預(yù)編譯聲明,代碼如下:#include"SocSvrDlg.h"http://對話框類,包含進來CSocListen::CSocListen(CSocSvrDlg*pDlgSocSvr){m_pDlgSocSvr=pDlgSocSvr;//初始化對話框指針}這樣,在套接字類中也可以通過成員變量使用對話框了。使用同樣的方法對CSocRecv類進行設(shè)置,使其也可以通過成員變量使用對話框。1.4、為套接字添加串行化讀寫信息的功能在服務(wù)器端的兩個套接字中,只有CSocRecv套接字是真正與客戶端套接字建立連接,發(fā)送與接收數(shù)據(jù)的,因此,我們只為該類添加串行化讀寫信息功能。在SocRecv.h文件中為類CSocRecv添加三個公有成員變量。CsocketFile*m_pCSocFile;Carchive*m_pCArcIn;Carchive*m_pCArcOut;1.5、在對話框中初始化套接字并偵聽連接請求在OnInitDialog函數(shù)中添加如下代碼:if(m_pCSocListen=newCSocListen(this)){if(m_pCSocListen->Create(1000))//創(chuàng)建端口號{m_lst_log.AddString("等待連接??");m_pCSocListen->Listen();}else{7m_lst_log.AddString("初始化失敗,請重新啟動程序");deletem_pCSocListen;//清除偵聽socket所占內(nèi)存}}else{m_lst_log.AddString("初始化失敗,請重新啟動程序");}上述代碼主要是創(chuàng)建并初始化ServSock套接字,并開始偵聽連接請求。1.6、接受連接請求由于是CSocListen類的*m_pCSocListen對象在偵聽連接請求,因此由該類來接受連接請求。首先,在SocListen.h文件中加入如下語句:#iinclude“SocRecv.h”然后,重載該類的OnAccept函數(shù),在該函數(shù)中添加如下代碼:CSocRecv*pCSocRecv;//接收客戶端消息類指針if(pCSocRecv=newCSocRecv(this->m_pDlgSocSvr)){if(Accept(*pCSocRecv)){pCSocRecv->m_pCSocFile=newCSocketFile(pCSocRecv);pCSocRecv->m_pCArcIn=newCArchive(pCSocRecv->m_pCSocFile,CArchive::load);pCSocRecv->m_pCArcOut=newCArchive(pCSocRecv->m_pCSocFile,CArchive::store);m_pDlgSocSvr->m_pCSocRecv=pCSocRecv;pCSocRecv=NULL;m_pDlgSocSvr->m_lst_log.AddString("連接成功,可以開始傳遞消息咯~");m_pDlgSocSvr->m_btn_send.EnableWindow(TRUE);}else{m_pDlgSocSvr->m_lst_log.AddString("試圖連接客戶端失敗~");deletepCSocRecv;}}else{m_pDlgSocSvr->m_lst_log.AddString("連接套接字初始化失敗~");}上述代碼首先調(diào)用Accept函數(shù)接受連接請求,然后為該連接創(chuàng)建一個CSocRecv8類型的套接字,并為該套接字關(guān)聯(lián)CArchive對象,使其能實現(xiàn)串行化傳輸信息的功能。最后把關(guān)聯(lián)好的套接字傳回給對話框?qū)ο蠊┢涫褂谩_@樣,對話框?qū)ο蟮某蓡T變量RecvSock套接字便與客戶端套接字之間建立了一條信息通道,信息將在兩個套接字之間傳遞。1.7、接收信息連接建立成功后,當(dāng)有信息到達服務(wù)器端時,就會引發(fā)SocRecv套接字對象的OnReceive函數(shù),因此需要重載CSocRecv類的OnReceive函數(shù)。添加代碼如下:CStringcsRecMsg;//接收到的信息(*m_pCArcIn)>>csRecMsg;//接收信息m_pDlgSocSvr->m_lst_log.AddString("客戶端發(fā)來的信息如下:");m_pDlgSocSvr->m_lst_log.AddString(csRecMsg);//添加到列表框//選中列表框中剛剛收到的消息m_pDlgSocSvr->m_lst_log.SetCurSel(m_pDlgSocSvr->m_lst_log.GetCount()-1);1.8、發(fā)送信息為對話框“發(fā)送”按鈕添加事件處理函數(shù)OnBTNSend(),代碼如下:voidCSocSvrDlg::OnBTNSend(){//TODO:AddyourcontrolnotificationhandlercodehereCStringcsSenMsg;//要發(fā)送的消息m_edt_senMsg.GetWindowText(csSenMsg);//獲得編輯框內(nèi)容if(csSenMsg==""){AfxMessageBox("空字符串,不能發(fā)送~");return;}m_lst_log.AddString("你發(fā)出的信息如下:");m_lst_log.AddString(csSenMsg);m_lst_log.SetCurSel(m_lst_log.GetCount()-1);*(m_pCSocRecv->m_pCArcOut)<<csSenMsg;m_pCSocRecv->m_pCArcOut->Flush();}9二、客戶端應(yīng)用程序設(shè)計(工程名稱SocClt)2.1、界面及各控件屬性界面如下:各控件屬性如下控件類型控件IDCaption屬性控件變量變量類型列表框IDC_LST_Logm_lst_logCListBox編輯框IDC_EDT_SenMsgm_edt_senMsgCEdit按鈕IDC_BTN_Sendm_btn_sendCButton列表框控件IDC_LST_Log的屬性“sort”值為false,屬性“HorizontalScroll”值為true。按鈕IDC_BTN_Send屬性Disable值為true。2.2、創(chuàng)建套接字類(從CSocket類派生)客戶端只需要一個套接字,命名為CSocSend。2.3、建立對話框類與套接字類的關(guān)聯(lián)首先,在SocCltDlg.h文件的開頭,語句#pragmaonce后面加入如下語句:classCSocSend;//聲明socket類然后,在該文件中為CSocCltDlg類添加一個公有成員變量,語句如下:10CSocSend*m_pCSocSend;//定義socket類指針再在CsocSend中添加對話框類的成員變量。首先,在SocSend.h文件的開頭,語句#pragmaonce后面加入如下語句:classCSocCltDlg;//聲明對話框類然后,在該文件中為CSocSend類添加一公有成員變量和一個構(gòu)造函數(shù),語句如下:CSocSend(CSocCltDlg*pDlgSocClt);CSocCltDlg*m_pDlgSocClt;//定義一個對話框類的指針接著,在SocSend.cpp文件中添加新的構(gòu)造函數(shù)的實現(xiàn)代碼,并添加一條關(guān)于CSocCltDlg.h文件的預(yù)編譯聲明,代碼如下:#include"SocCltDlg.h"http://對話框類,包含進來CSocSend::CSocSend(CSocCltDlg*pDlgSocClt){m_pDlgSocClt=pDlgSocClt;}這樣,便完成了對話框和套接字之間的連接了。2.4、為套接字添加串行化讀寫信息的功能在SocSend.h文件中,為類CSocSend添加三個公有成員變量,代碼如下:CSocketFile*m_pCSocFile;CArchive*m_pCArcIn;CArchive*m_pCArcOut;2.5、在對話框中初始化套接字并建立連接在對話框類的OnInitDialog函數(shù)中添加如下代碼m_lst_log.AddString("正在連接??");if(m_pCSocSend=newCSocSend(this)){if(m_pCSocSend->Create())//創(chuàng)建套接字{//if(m_pCSocSend->Connect("localhost",1000))//服務(wù)器名稱、端口號if(m_pCSocSend->Connect("cy-sys",1000))//服務(wù)器名稱、端口號{m_pCSocSend->m_pCSocFile=newCSocketFile(m_pCSocSend);m_pCSocSend->m_pCArcIn=newCArchive(m_pCSocSend->m_pCSocFile,CArchive::load);m_pCSocSend->m_pCArcOut=newCArchive(m_pCSocSend->m_pCSocFile,CArchive::store);m_lst_log.AddString("連接成功,可以開始傳遞消息咯~");m_btn_send.EnableWindow(TRUE);}else11{m_lst_log.AddString("連接不成功~");deletem_pCSocSend;//清除socket所占內(nèi)存}}else{m_lst_log.AddString("初始化失敗,請重新啟動程序");deletem_pCSocSend;//清除socket所占內(nèi)存}}else{m_lst_log.AddString("初始化失敗,請重新啟動程序");}2.6、接收消息消息到來時,會引發(fā)套接字的OnReceive消息
溫馨提示
- 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)方式做保護處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 廣東水利電力職業(yè)技術(shù)學(xué)院《建筑學(xué)前沿及研究方法》2023-2024學(xué)年第一學(xué)期期末試卷
- 廣東汕頭幼兒師范高等專科學(xué)?!吨袊鴳蚯费芯俊?023-2024學(xué)年第一學(xué)期期末試卷
- 廣東茂名農(nóng)林科技職業(yè)學(xué)院《歷史學(xué)課程教學(xué)論》2023-2024學(xué)年第一學(xué)期期末試卷
- 當(dāng)政府遇上互聯(lián)網(wǎng)(復(fù)旦大學(xué))學(xué)習(xí)通測試及答案
- 【優(yōu)化探究】2022屆高三物理一輪復(fù)習(xí)知能檢測:7-1電場力的性質(zhì)-
- 【全程復(fù)習(xí)方略】2020-2021學(xué)年高中數(shù)學(xué)(人教A版選修2-2)課時作業(yè)-2.2.1.2-分析法
- 永州市2025屆高三高考第二次模擬考試(二模)地理試卷
- 2025年人教版八年級數(shù)學(xué)寒假預(yù)習(xí) 第08講 平行四邊形的判定(1個知識點+6大考點舉一反三+過關(guān)測試)
- 《產(chǎn)品知識講解》課件
- 河南省周口市第三初級中學(xué)2024-2025學(xué)年七年級上學(xué)期期末測試英語試卷(含答案無聽力部分)
- 物業(yè)暖通工程師年工作總結(jié)及年工作計劃
- 供應(yīng)鏈年終工作總結(jié)報告
- 肌鈣蛋白升高詳細解讀
- 2024年香港中旅國際投資有限公司招聘筆試參考題庫含答案解析
- 醬油培訓(xùn)課件
- Zippo-2024年美版年冊集合
- 重大隱患判定標準培訓(xùn)課件
- 畫法幾何及機械制圖課件
- 棋牌游戲自審自查報告
- 地質(zhì)災(zāi)害風(fēng)險調(diào)查評價項目招標文件
- JJF 2088-2023大型蒸汽滅菌器溫度、壓力、時間參數(shù)校準規(guī)范
評論
0/150
提交評論