版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
編號(hào):計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)說明書`` 題目:基于TCP協(xié)議網(wǎng)上聊天程序系別:專業(yè):學(xué)生姓名:學(xué)號(hào):指導(dǎo)教師:2023年3月27日目錄1設(shè)計(jì)任務(wù)21.1系統(tǒng)設(shè)計(jì)目標(biāo)21.2聊天程序的功能22系統(tǒng)分析22.1系統(tǒng)理論根底22.2客戶機(jī)/效勞器模式32.3Sokect介紹42.4系統(tǒng)開發(fā)環(huán)境52.5系統(tǒng)結(jié)構(gòu)設(shè)計(jì)53總體設(shè)計(jì)53.1體系結(jié)構(gòu)設(shè)計(jì)53.2網(wǎng)絡(luò)通信設(shè)計(jì)63.3模塊設(shè)計(jì)83.31效勞器83.32客戶端94詳細(xì)設(shè)計(jì)104.1設(shè)計(jì)效勞器和客戶端的界面104.2實(shí)現(xiàn)效勞器和客戶端通過網(wǎng)絡(luò)通信114.3實(shí)現(xiàn)多個(gè)客戶端之間的實(shí)時(shí)聊天功能115總結(jié)166使用說明16參考文獻(xiàn)201設(shè)計(jì)任務(wù)1.1系統(tǒng)設(shè)計(jì)目標(biāo)深入理解計(jì)算機(jī)網(wǎng)絡(luò)根本原理,將書本上抽象的概念與具體的實(shí)現(xiàn)技術(shù)相結(jié)合,體會(huì)網(wǎng)絡(luò)協(xié)議的設(shè)計(jì)與實(shí)現(xiàn)過程,以及專業(yè)技術(shù)人員所使用的根本方法和技巧。基于TCP協(xié)議網(wǎng)上聊天程序?qū)崿F(xiàn)一簡單的聊天程序,實(shí)現(xiàn)網(wǎng)上聊天,包括效勞器和客戶端。要求:〔1〕支持多人聊天。〔2〕客戶端具有圖形化用戶界面。1.2聊天程序的功能客戶端使用簡便,效勞器端運(yùn)行穩(wěn)定。客戶端與效勞器端可運(yùn)行在多種系統(tǒng)平臺(tái),具有良好的兼容性能。客戶端與效勞器端功能獨(dú)立,可獨(dú)立運(yùn)行在不同的計(jì)算機(jī)上或運(yùn)行在同一臺(tái)計(jì)算機(jī)上,具有最大的靈活性。根據(jù)任課教師的要求及我自己的編程能力,寫出以下的功能:1、登錄時(shí)只需要提供用戶名即可,無需輸入密碼。2、允許多人在線聊天。3、聊天發(fā)送的消息包括:用戶名稱、發(fā)送時(shí)間及正文。4、某用戶剛登錄效勞器時(shí),效勞器需對(duì)其發(fā)送實(shí)時(shí)在線用戶列表。5、某用戶登錄或退出程序時(shí)都需要給效勞器發(fā)送一個(gè)消息以通知其他用戶。6、能夠查看聊天記錄。2系統(tǒng)分析2.1系統(tǒng)理論根底TCP/IP的特點(diǎn)
TCP/IP協(xié)議的核心局部是傳輸層協(xié)議(TCP、UDP),網(wǎng)絡(luò)層協(xié)議(IP)和物理接口層,這三層通常是在操作系統(tǒng)內(nèi)核中設(shè)計(jì)。因此用戶一般不涉及。TCP是面向連接的,通信雙方保持一條通路,好比目前的線,使用telnet登陸B(tài)BS,用的就是TCP協(xié)議;UDP是無連接的,通信雙方都不保持對(duì)方的狀態(tài),瀏覽器訪問Internet時(shí)使用的協(xié)議就是基于UDP協(xié)議的。編程時(shí),編程界面有兩種形式:一、是由內(nèi)核心直接提供的系統(tǒng)調(diào)用;二、使用以庫函數(shù)方式提供的各種函數(shù)。前者為核內(nèi)設(shè)計(jì),后者為核外設(shè)計(jì)。用戶效勞要通過核外的應(yīng)用程序才能設(shè)計(jì),所以要使用套接字(socket)來設(shè)計(jì)。2.2客戶機(jī)/效勞器模式C/S結(jié)構(gòu)〔Client/Server結(jié)構(gòu)〕是大家熟知的客戶機(jī)和效勞器結(jié)構(gòu)。它是軟件系統(tǒng)體系結(jié)構(gòu),通過它可以充分利用兩端硬件環(huán)境的優(yōu)勢(shì),將任務(wù)合理分配到Client端和Server端來實(shí)現(xiàn),降低了系統(tǒng)的通訊開銷。目前大多數(shù)應(yīng)用軟件系統(tǒng)都是Client/Server形式的兩層結(jié)構(gòu),由于現(xiàn)在的軟件應(yīng)用系統(tǒng)正在向分布式的Web應(yīng)用開展,Web和Client/Server應(yīng)用都可以進(jìn)行同樣的業(yè)務(wù)處理,應(yīng)用不同的模塊共享邏輯組件;因此,內(nèi)部的和外部的用戶都可以訪問新的和現(xiàn)有的應(yīng)用系統(tǒng),通過現(xiàn)有應(yīng)用系統(tǒng)中的邏輯可以擴(kuò)展出新的應(yīng)用系統(tǒng)。這也就是目前應(yīng)用系統(tǒng)的開展方向。
首先效勞器方要啟動(dòng),并根據(jù)請(qǐng)求提供相應(yīng)效勞:
〔1〕翻開一通信通道并告知本地主機(jī),它在某一公認(rèn)地址端口上(如為80)接受客戶請(qǐng)求。
〔2〕等待客戶請(qǐng)求到達(dá)該端口。
〔3〕接收到重復(fù)效勞請(qǐng)求,處理該請(qǐng)求并發(fā)送應(yīng)答信號(hào)。接收并發(fā)效勞請(qǐng)求,要激活一新進(jìn)程來處理這個(gè)客戶請(qǐng)求。新進(jìn)程處理此客戶請(qǐng)求,并不需要對(duì)其他請(qǐng)求做出應(yīng)答。效勞完成后,關(guān)閉此新進(jìn)程與客戶的通信鏈路,并終止。
〔4〕返回第二步,等待另外的客戶請(qǐng)求
〔5〕關(guān)閉效勞器。
客戶方:
〔1〕翻開一通信通道,并連接到效勞器所在主機(jī)的特定端口。
〔2〕向效勞器發(fā)出效勞請(qǐng)求報(bào)文,等待并接收應(yīng)答;繼續(xù)提出請(qǐng)求。
〔3〕請(qǐng)求結(jié)束后關(guān)閉通信通道并終止。
從上面的描述過程可知:
〔1〕客戶與效勞器進(jìn)程的作用是非對(duì)稱的。因此編碼不同。
〔2〕效勞進(jìn)程一般是先于客戶請(qǐng)求啟動(dòng)的。只要系統(tǒng)運(yùn)行,該進(jìn)程一直存在,直到正常終止或者強(qiáng)迫終止。
在TCP/IP網(wǎng)絡(luò)中兩個(gè)進(jìn)程間的相互作用的主機(jī)模式是客戶機(jī)/效勞器模式(Client/Servermodel)。該模式的建立基于以下兩點(diǎn):1、非對(duì)等作用;2、通信完全是異步的??蛻魴C(jī)/效勞器模式在操作過程中采取的是主動(dòng)請(qǐng)求效勞響應(yīng)的方式。2.3Socket介紹Socket是建立在傳輸層協(xié)議(主要是TCP和UDP)上的一種套接字標(biāo)準(zhǔn),最初是由美國加州Berkley大學(xué)提出,它定義兩臺(tái)計(jì)算機(jī)間進(jìn)行通信的標(biāo)準(zhǔn)〔也是一種編程標(biāo)準(zhǔn)〕,如果說兩臺(tái)計(jì)算機(jī)是利用一個(gè)“通道〞進(jìn)行通信,那么這個(gè)“通道〞的兩端就是兩個(gè)套接字。套接字屏蔽了底層通信軟件和具體操作系統(tǒng)的差異,使得任何兩臺(tái)安裝了TCP協(xié)議軟件和實(shí)現(xiàn)了套接字標(biāo)準(zhǔn)的計(jì)算機(jī)之間的通信成為可能。微軟的WindowsSocket標(biāo)準(zhǔn)(簡稱Winsock)對(duì)Berkley的套接字標(biāo)準(zhǔn)進(jìn)行了擴(kuò)展,利用標(biāo)準(zhǔn)的Socket的方法,可以同任何平臺(tái)上的Socket進(jìn)行通信;利用其擴(kuò)展,可以更有效地實(shí)現(xiàn)在Windows平臺(tái)上計(jì)算機(jī)間的通信。Socket減輕了編寫計(jì)算機(jī)間通信軟件的難度;標(biāo)準(zhǔn)的Socket的應(yīng)用程序框架如下:Server方:Socket()[新建一個(gè)Socket]--Bind()[同效勞器地址綁定]--Listen()--Accept()--blockwait--read()[接受消息,在windows平臺(tái)中,方法為send(TCP),或者是sendto(UDP)]--處理效勞請(qǐng)求--Write()[發(fā)送消息],在windows平臺(tái)中,方法為send(TCP),或者為sendto(UDP)。Client方相對(duì)簡單:Socket()--Connect()[通過一定的port連接特定的效勞器,這是與效勞器建立連接]--Write()--Read()。Socket可以是基于TCP的,也可以是基于UDP,同時(shí)Socket甚至建立在其他的協(xié)議,比方IPX/SPX,DECNet等。在新建一個(gè)Socket時(shí),可以指定新建何類Socket。Bind()用來同效勞器的地址綁定,如果一個(gè)主機(jī)只有一個(gè)IP地址,實(shí)際上綁定的作用就相對(duì)多余了。Listen()開始監(jiān)聽網(wǎng)絡(luò),Accept()用于接受連接,其返回值是保持同客戶機(jī)聯(lián)系的Socket。在VC++2023中,其底層的Socket也應(yīng)該是Windows的Socket。Inprise在VC++2023中對(duì)WindowsSocket進(jìn)行了有效的封裝,使得用戶可以很方便地編寫網(wǎng)絡(luò)通信程序。Socket系統(tǒng)調(diào)用包括創(chuàng)立Socket、將創(chuàng)立的Socket與本地端口綁定、建立Socket連接效勞器、監(jiān)聽是否有連接、請(qǐng)求數(shù)據(jù)的可控緩沖發(fā)送和可控緩沖接收,到最后關(guān)閉Socket。首先在效勞器方,利用socket()函數(shù)建立流式套接字,返回套接字號(hào)s,接著利用bind()函數(shù)將套接字s與本地地址綁定,緊接著利用listen()函數(shù)通知TCP,監(jiān)聽客戶方,效勞器準(zhǔn)備接收連接,沒有連接的話,效勞器方通過closesocket()關(guān)閉套接字s,效勞結(jié)束。有連接的話,在客戶方,通過socket()函數(shù)建立流式套接字s,此時(shí)在效勞器方,建立連接,通過accept()返回,得到新的套接字ns,客戶方通過connect()將套接字s與遠(yuǎn)程地址連接,此時(shí)效勞器方/客戶方在ns/s上讀/寫數(shù)據(jù),直到交換完成。交換完成后,效勞器方/客戶方關(guān)閉套接字ns/s,最后效勞器方通過closesocket()關(guān)閉最初套接字s,效勞結(jié)束。2.4系統(tǒng)開發(fā)環(huán)境本系統(tǒng)開發(fā)環(huán)境采用VisualStudio2023。編譯語言采用C++。2.5系統(tǒng)結(jié)構(gòu)設(shè)計(jì)本系統(tǒng)采用C/S結(jié)構(gòu),最重要的特點(diǎn)是非對(duì)等相互作用,即客戶與效勞器處于不平等的地位,效勞器擁有客戶所不具備的硬軟件資源,客戶和效勞器分別是效勞的請(qǐng)求者和提供者。網(wǎng)絡(luò)中各個(gè)機(jī)器的資源是不平等的,網(wǎng)絡(luò)的真正目的就是共享這些不均等資源源,非對(duì)等相互作用特點(diǎn)也正好表達(dá)和適應(yīng)了客觀現(xiàn)實(shí)中資源的不均等現(xiàn)象。局域網(wǎng)上不同主機(jī)進(jìn)程間通信完全是異步的,通信時(shí)機(jī)具有隨機(jī)性,所以必須用這種為通信雙方的數(shù)據(jù)交換提供同步的機(jī)制。3總體設(shè)計(jì)3.1體系結(jié)構(gòu)設(shè)計(jì)通常的通信工具,都采用客戶機(jī)/效勞器(C/S)體系結(jié)構(gòu),C/S結(jié)構(gòu)是這樣的一種結(jié)構(gòu):它包括一個(gè)客戶機(jī)(或前端),一個(gè)效勞器(或稱后端),客戶機(jī)的作用是訪問和處理遠(yuǎn)程效勞器上的數(shù)據(jù),效勞器的作用是接收和處理客戶機(jī)的數(shù)據(jù)請(qǐng)求。有時(shí),可能有多個(gè)客戶向同一個(gè)效勞器同時(shí)請(qǐng)求效勞,這就需要效勞器決定怎樣處理這些請(qǐng)求。Client/Server結(jié)構(gòu)是當(dāng)前數(shù)據(jù)庫應(yīng)用程序中極為流行的一種方式。尤其是網(wǎng)絡(luò)技術(shù)的開展,使得當(dāng)前很多系統(tǒng)都采用這種方式進(jìn)行構(gòu)造,其最大的優(yōu)點(diǎn)是將計(jì)算機(jī)工作任務(wù)分別由客戶端和效勞器端來共同完成,這樣有利于充分合理的利用系統(tǒng)資源。另外它的效勞器端還可以將信息集中起來,任何客戶機(jī)都可以通過訪問效勞器而獲得所需的信息。Client/Server模型最終可歸結(jié)為一種“請(qǐng)求/應(yīng)答〞關(guān)系。一個(gè)請(qǐng)求總是首先被客戶發(fā)出,然后效勞器總是被動(dòng)地接收請(qǐng)求,返回客戶需要的結(jié)果。在客戶發(fā)出一個(gè)請(qǐng)求之前,效勞進(jìn)程一直處于休眠狀態(tài)。一個(gè)客戶提出請(qǐng)求后,效勞進(jìn)程被“喚醒〞并且為客戶提供效勞,對(duì)客戶的請(qǐng)求做出所需要的應(yīng)答。如下列圖所示:圖3.1客戶機(jī)/效勞器通信結(jié)構(gòu)示圖在客戶端啟動(dòng)后,客戶端計(jì)算得到本地網(wǎng)絡(luò)的播送地址,進(jìn)行播送查找效勞器端,效勞器接收到客戶端的播送信息后返回效勞器地址,那么客戶端接收、驗(yàn)證信息并記錄效勞器端地址,然后客戶端啟動(dòng)定時(shí)期,定時(shí)發(fā)送信息到效勞器,以告知效勞器自己在線,然后效勞器返回在線用戶列表,效勞器依靠客戶端發(fā)送的信息來更新維護(hù)在線用戶列表。在客戶端與效勞器盡心數(shù)據(jù)交換,擁有了在線用戶列表后,就可以選擇IP進(jìn)行客戶端之間的點(diǎn)對(duì)點(diǎn)信息交流了。如果效勞器不在線,那么客戶端會(huì)提示用戶退出,在一定的時(shí)間后自動(dòng)退出。3.2網(wǎng)絡(luò)通信設(shè)計(jì)在調(diào)用了Windowssockets的啟動(dòng)函數(shù)WSACleanup()之后才能進(jìn)行其他的Socket系統(tǒng)調(diào)用,但啟動(dòng)函數(shù)WSAStartup()是為了建立與WindowsSocketsDLL的連接,因此在VisualStudio2023所建立工程的工程設(shè)置中的連接的庫模塊必須進(jìn)行設(shè)置,在其中的link欄內(nèi)的對(duì)象/庫模塊中參加“Ws2_32.lib〞,才能真正建立建立與WindowsSocketsDLL的連接。其他的Socket系統(tǒng)調(diào)用包括創(chuàng)立Socket、將創(chuàng)立的Socket與本地端口綁定、建立Socket連接效勞器、監(jiān)聽是否有連接、請(qǐng)求數(shù)據(jù)的可控緩沖發(fā)送和可控緩沖接收,到最后關(guān)閉Socket。具體流程圖如1所示。首先在效勞器方,利用socket()函數(shù)建立流式套接字,返回套接字號(hào)s,接著利用bind()函數(shù)將套接字s與本地地址綁定,緊接著利用listen(0函數(shù)通知TCP,監(jiān)聽客戶方,效勞器準(zhǔn)備接收連接,沒有連接的話,效勞器方通過closesocket()關(guān)閉套接字s,效勞結(jié)束。有連接的話,在客戶方,通過socket()函數(shù)建立流式套接字s,此時(shí)在效勞器方,建立連接,通過accept()返回,得到新的套接字ns,客戶方通過connect()將套接字s與遠(yuǎn)程地址連接,此時(shí)效勞器方/客戶方在ns/s上讀/寫數(shù)據(jù),直到交換完成。交換完成后,效勞器方/客戶方關(guān)閉套接字ns/s,最后效勞器方通過closesocket()關(guān)閉最初套接字s,效勞結(jié)束。具體設(shè)計(jì)過程如圖3.2所示。效勞器方效勞器方Socket()建立流式接字,返回套接字號(hào)s客戶方bind()套接字s與本地地址綁定listen()通知TCP效勞器準(zhǔn)備接收連接accept()接收連接,等待客戶端的連接建立連接,accept()返回,得到新套接nsRecv()/send()在ns上讀/寫數(shù)據(jù),直到完成交換closesocket(),關(guān)閉套接字nsclosesocket()關(guān)閉最初套接字s,效勞結(jié)束Socket()建立流式套接字號(hào)sconnect()將套接字s與遠(yuǎn)程地址連接Recv()/send()在s上讀/寫數(shù)據(jù),直到完成交換closesocket()關(guān)閉套接字s,結(jié)束TCP圖3.2面向連接的套接字的系統(tǒng)調(diào)用流程圖3.3模塊設(shè)計(jì)3.31效勞器首先運(yùn)行效勞器,效勞器偵聽端口消息,等待客戶端向其建立連接的申請(qǐng),一旦接收到客戶端的連接請(qǐng)求,效勞器將返回一個(gè)新的套接字描述符,通過該描述符調(diào)用數(shù)據(jù)傳輸函數(shù)即可與客戶端進(jìn)行數(shù)據(jù)的收發(fā)。效勞器假設(shè)接收的是登陸信息,向該用戶發(fā)送在線用戶列表,并更新效勞器的在線用戶列表;假設(shè)收到的是發(fā)送信息,效勞器解析信息,然后通過播送消息,向其所有線用戶列表發(fā)送消息。效勞器端流程圖如下。向該用戶發(fā)送在線用戶列表向該用戶發(fā)送在線用戶列表開始偵聽端口消息解析消息向其所有在線用戶發(fā)送消息首次登陸更新效勞器在線用戶列表收到消息運(yùn)行效勞器是否是播送消息播送消息圖3.31效勞器流程圖3.32客戶端在運(yùn)行效勞器之后,運(yùn)行客戶端??蛻舳耸紫认蛐谄魈岢鼋⑦B接請(qǐng)求,然后建立一個(gè)套接字描述符,通過該描述符調(diào)用數(shù)據(jù)傳輸函數(shù)即可與效勞端進(jìn)行數(shù)據(jù)的收發(fā)。用戶登錄成功后,向效勞器發(fā)送登陸消息,并更新本地在線用戶列表,然后通過效勞器實(shí)現(xiàn)與其他客戶聊天;當(dāng)客戶退出,向效勞器發(fā)送下線消息??蛻舳肆鞒虉D如下。開始開始開始開始開始開始運(yùn)行客戶端運(yùn)行客戶端運(yùn)行客戶端運(yùn)行客戶端運(yùn)行客戶端運(yùn)行客戶端用戶登陸用戶登陸用戶登陸用戶登陸用戶登陸用戶登陸給效勞器發(fā)送登陸消息登陸成功登陸成功向該用戶發(fā)送在線用戶列表登陸成功向該用戶發(fā)送在線用戶列表否給效勞器發(fā)送登陸消息登陸成功登陸成功向該用戶發(fā)送在線用戶列表登陸成功向該用戶發(fā)送在線用戶列表是顯示主頁面顯示主頁面顯示主頁面是顯示主頁面顯示主頁面顯示主頁面給效勞器發(fā)送下線消息向其所有在線用戶發(fā)送消息向其所有在線用戶發(fā)送消息是給效勞器發(fā)送下線消息向其所有在線用戶發(fā)送消息向其所有在線用戶發(fā)送消息更新本地在線用戶列表更新本地在線用戶列表更新本地在線用戶列表更新本地在線用戶列表更新本地在線用戶列表更新本地在線用戶列表與其他用戶進(jìn)行聊天與其他用戶進(jìn)行聊天與其他用戶進(jìn)行聊天與其他用戶進(jìn)行聊天與其他用戶進(jìn)行聊天與其他用戶進(jìn)行聊天退出退出退出退出退出退出圖3.32客戶端流程圖4詳細(xì)設(shè)計(jì)4.1設(shè)計(jì)效勞器和客戶端的界面分別為客戶端和效勞器創(chuàng)立基于對(duì)話框的MFC工程。分別為其添加顯示信息和輸入信息的文本控件和按鈕,并為其指定適當(dāng)?shù)膶傩?。效勞器和客戶端的運(yùn)行界面分別如圖4.1——4.3所示。圖4.1效勞器運(yùn)行界面設(shè)計(jì)圖4.2客戶端登陸界面設(shè)計(jì)圖4.3客戶端運(yùn)行界面設(shè)計(jì)4.2實(shí)現(xiàn)效勞器和客戶端通過網(wǎng)絡(luò)通信效勞器和客戶端通過定義CSocket類的子類來重載CSocket類中的成員函數(shù)完成效勞器與客戶端之間的網(wǎng)絡(luò)通信。效勞器和客戶端的交互包括客戶端登錄效勞器,效勞器將客戶名添加至客戶列表中,以及客戶下線后,效勞器和在線客戶將下線客戶從客戶列表中刪除等。4.3實(shí)現(xiàn)多個(gè)客戶端之間的實(shí)時(shí)聊天功能由于客戶端/效勞器模式,客戶在進(jìn)行聊天時(shí),需要把待發(fā)送的消息發(fā)送至效勞器;效勞器接收到消息后,經(jīng)過查詢客戶列表,尋找接受的客戶名后,將消息轉(zhuǎn)發(fā)至在線客戶處。由于效勞器與客戶端交互時(shí),還需接收客戶端的登錄信息,故將接收客戶端的登錄信息和接收消息發(fā)在同一個(gè)接收函數(shù)中。根據(jù)以上步驟,對(duì)實(shí)現(xiàn)聊天工具的效勞器和客戶端的關(guān)鍵代碼解說如下?!?〕效勞器初始化,開始監(jiān)聽客戶端的連接請(qǐng)求,具體代碼如下:BOOLCChatServerApp::InitInstance(){if(!AfxSocketInit())//套接字初始化失敗 { AfxMessageBox(IDP_SOCKETS_INIT_FAILED);returnFALSE; } AfxEnableControlContainer(); CServerSocket*m_pSocket;//自定義的CSocket類的子類 m_pSocket=newCServerSocket;if(!m_pSocket->Create(9999))//創(chuàng)立套接字 { AfxMessageBox(_T("創(chuàng)立Socket失?。。?!"));returnFALSE; }if(!m_pSocket->Listen())//監(jiān)聽客戶端的連接請(qǐng)求 { AfxMessageBox(_T("創(chuàng)立偵聽發(fā)生錯(cuò)誤!??!"));returnFALSE; }(2〕客戶端登陸至效勞器,具體代碼如下:voidCLoginDlg::OnOK(){ UpdateData();//獲取文本框中數(shù)據(jù)if(!m_pSocket->Create())//創(chuàng)立套接字 { AfxMessageBox(_T("網(wǎng)絡(luò)創(chuàng)立錯(cuò)誤?。?!")); m_pSocket->Close();return; }if(!m_pSocket->Connect(m_strServer,9999))//連接至效勞器 { AfxMessageBox(_T("連接效勞器失敗?。?!")); m_pSocket->Close();return; } Headerhead; head.type=LOGIN_IO; head.len=m_strName.GetLength(); m_pSocket->Send((char*)&head,sizeof(Header));//發(fā)送客戶信息至效勞器 m_pSocket->Send(m_strName,m_strName.GetLength()); theApp.m_strName=m_strName; CDialog::OnOK();}〔3〕效勞器接收新登錄客戶的信息,具體代碼如下:voidCClientSocket::OnReceive(intnErrorCode){ charbuff1[sizeof(Header)]; memset(buff1,0,sizeof(buff1)); Receive(buff1,sizeof(buff1)); Header*header=(Header*)buff1; intlength=header->len; chartype=header->type; if(type==LOGIN_IO)//如果收到的是登錄信息 { charbuff[1000]; memset(buff,0,sizeof(buff)); Receive(buff,length);//接受客戶登錄信息 CTimetime=CTime::GetCurrentTime();//獲取當(dāng)前系統(tǒng)時(shí)間 CStringt=time.Format("%Y-%m-%d%H:%M:%S");//時(shí)間格式 CEdit*p_Edit=(CEdit*)::AfxGetMainWnd()->GetDlgItem(IDC_EDIT_INFO); CStringstrTemp=t+":"+CString(buff)+"進(jìn)入\r\n";//顯示登錄信息 p_Edit->ReplaceSel(strTemp);//更新在線客戶列表 m_strName=buff; m_dlgServer->UpdateUser(this); } if(type==SEND_MESSAGE)//如果接受的是客戶發(fā)送信息 { charbuff[1000]; memset(buff,0,sizeof(buff)); Receive(buff,sizeof(buff));//接收消息內(nèi)容 CClientSocket*curr=NULL; POSITIONpos=clist->GetHeadPosition(); while(pos!=NULL)//將消息發(fā)至在線客戶 { curr=(CClientSocket*)clist->GetNext(pos); curr->Send((char*)header,sizeof(Header)); curr->Send(buff,sizeof(buff)); } } CSocket::OnReceive(nErrorCode);}〔4〕客戶發(fā)送消息,先將消息發(fā)至效勞器,具體代碼如下:voidCMyChatDlg::OnSend(){ UpdateData(); if(m_strMessage=="") { AfxMessageBox(_T("不能發(fā)送空消息?。?!")); CEdit*pEdit=(CEdit*)GetDlgItem(IDC_EDIT_MESSAGE); pEdit->SetFocus(); return; } Headerhead; head.type=SEND_MESSAGE; head.len=m_strMessage.GetLength(); CTimetime=CTime::GetCurrentTime(); CStringt=time.Format("%H:%M:%S"); CStringnikeName=theApp.m_strName; CStringstr=nikeName+""+t+"\r\n"+""+m_strMessage; m_pSocket->Send((char*)&head,sizeof(Header));//將發(fā)送時(shí)間和收信客戶信息發(fā)至效勞器 if(m_pSocket->Send((LPCTSTR)str,str.GetLength()))//發(fā)送信息內(nèi)容 { m_strMessage=""; UpdateData(FALSE); CEdit*pEdit=(CEdit*)GetDlgItem(IDC_EDIT_MESSAGE); pEdit->SetFocus(); }else { AfxMessageBox(_T("網(wǎng)絡(luò)傳輸錯(cuò)誤!")); }}〔5〕效勞器接收消息并轉(zhuǎn)發(fā),具體代碼如下:voidCClientSocket::OnReceive(intnErrorCode){ charbuff1[sizeof(Header)]; memset(buff1,0,sizeof(buff1)); Receive(buff1,sizeof(buff1)); Header*header=(Header*)buff1; intlength=header->len; chartype=header->type; if(type==LOGIN_IO)//如果收到的是登錄信息 { charbuff[1000]; memset(buff,0,sizeof(buff)); Receive(buff,length);//接受客戶登錄信息 CTimetime=CTime::GetCurrentTime();//獲取當(dāng)前系統(tǒng)時(shí)間 CStringt=time.Format("%Y-%m-%d%H:%M:%S");//時(shí)間格式 CEdit*p_Edit=(CEdit*)::AfxGetMainWnd()->GetDlgItem(IDC_EDIT_INFO); CStringstrTemp=t+":"+CString(buff)+"進(jìn)入\r\n";//顯示登錄信息 p_Edit->ReplaceSel(strTemp);//更新在線客戶列表 m_strName=buff; m_dlgServer->UpdateUser(this); } if(type==SEND_MESSAGE)//如果接受的是客戶發(fā)送信息 { charbuff[1000]; memset(buff,0,sizeof(buff)); Receive(buff,sizeof(buff));//接收消息內(nèi)容 CClientSocket*curr=NULL; POSITIONpos=clist->GetHeadPosition(); while(pos!=NULL)//將消息發(fā)至在線客戶 { curr=(CClientSocket*)clist->GetNext(pos); curr->Send((char*)header,sizeof(Header)); curr->Send(buff,sizeof(buff)); } } CSocket::OnReceive(nErrorCode);}〔6〕客戶端接收效勞器轉(zhuǎn)發(fā)的消息,具體代碼如下:BOOLCMyChatDlg::GetMessage()//接受效勞器轉(zhuǎn)發(fā)的信息{ charbuff[1000]; memset(buff,0,sizeof(buff)); m_pSocket->Receive(buff,sizeof(buff),0); CStringstrTemp=buff; strTemp+=_T("\r\n"); m_MessageList.ReplaceSel(strTemp);//顯示接受到的信息 returnTRUE;}(7〕客戶下線后,效勞器將下線的客戶從客戶列表中刪除,具體代碼如下:voidCClientSocket::OnClose(intnErrorCode)//效勞器通過失去連接錯(cuò)誤碼獲知下線的客戶{ POSITIONpos=clist->Find(this); if(pos!=NULL) { clist->RemoveAt(pos);//將下線客戶信息從列表中刪除 CTimetime=CTime::GetCurrentTime(); CStringt=time.Format("%Y-%m-%d%H:%M:%S"); CEdit*p_Edit=(CEdit*)m_dlgServer->GetDlgItem(IDC_EDIT_INFO); CStringstrTemp=t+":"+this->m_strName+"離開\r\n"; p_Edit->ReplaceSel(strTemp);//顯示客戶下線信息 m_dlgServer->UpdateUser(this); this->Close();//關(guān)閉與下線客戶連接的套接字 deletethis; } CSocket::OnClose(nErrorCode);}〔8〕其他客戶下線后,客戶端更新在線用戶列表,具體代碼如下:voidCMyChatDlg::UpdateUser(){ charbuff[1000]; memset(buff,0,sizeof(buff)); m_pSocket->Receive(buff,sizeof(buff),0); //接收用戶下線信息 CStringuser_info=buff; CStringarray[100]; intb=0; for(inti=0;i<user_info.GetLength();i++)//查找當(dāng)前在線用戶 { if(i!=(user_info.GetLength()-1)) { if(user_info[i]=='&') { b++; } else { array[b]=array[b]+user_info[i]; } } } m_UserList.ResetContent(); for(intj=0;j<b+1;j++)//更新在線用戶列表 { m_UserList.AddString(array[j]);
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- Module 4 Unit 2 What can you see(說課稿)-2024-2025學(xué)年外研版(一起)英語三年級(jí)上冊(cè)001
- 5《雷雨》說課稿 2023-2024學(xué)年統(tǒng)編版高中語文必修下冊(cè)
- 2023-2024學(xué)年天津市中小學(xué)生mixly創(chuàng)意編程 第9課 LED創(chuàng)意設(shè)計(jì)-說課稿
- 二零二五年度新型節(jié)能門窗研發(fā)與推廣合作合同4篇
- 二零二五版醫(yī)藥保健品門店承包管理服務(wù)合同4篇
- 2025年中國鄉(xiāng)村旅游行業(yè)市場(chǎng)深度分析及發(fā)展前景預(yù)測(cè)報(bào)告
- 二零二五版房屋互換及社區(qū)公益項(xiàng)目合作協(xié)議3篇
- 高速公路交通安全宣傳教育活動(dòng)合同(二零二五版)3篇
- 6 《 花兒草兒真美麗》(說課稿)2023-2024學(xué)年統(tǒng)編版道德與法治一年級(jí)下冊(cè)
- 2025版生態(tài)旅游區(qū)設(shè)施裝修設(shè)計(jì)合同范本4篇
- 2205雙相不銹鋼的焊接工藝
- 2023年全國高中數(shù)學(xué)聯(lián)賽江西省預(yù)賽試題及答案
- 啤酒廠糖化車間熱量衡算
- 英文標(biāo)點(diǎn)符號(hào)用法(句號(hào)分號(hào)冒號(hào)問號(hào)感嘆號(hào))(課堂)課件
- 22部能夠療傷的身心靈療愈電影
- 領(lǐng)導(dǎo)干部有效授權(quán)的技巧與藝術(shù)課件
- DB37-T 1915-2020 安全生產(chǎn)培訓(xùn)質(zhì)量控制規(guī)范-(高清版)
- 陜西省商洛市各縣區(qū)鄉(xiāng)鎮(zhèn)行政村村莊村名居民村民委員會(huì)明細(xì)
- 實(shí)習(xí)生請(qǐng)假條
- 光伏電站繼電保護(hù)運(yùn)行規(guī)程
- 廚房的管理流程與制度及廚房崗位工作流程
評(píng)論
0/150
提交評(píng)論