基于TCP協(xié)議網(wǎng)上聊天程序(共22頁)_第1頁
基于TCP協(xié)議網(wǎng)上聊天程序(共22頁)_第2頁
基于TCP協(xié)議網(wǎng)上聊天程序(共22頁)_第3頁
基于TCP協(xié)議網(wǎng)上聊天程序(共22頁)_第4頁
基于TCP協(xié)議網(wǎng)上聊天程序(共22頁)_第5頁
已閱讀5頁,還剩17頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1、精選優(yōu)質(zhì)文檔-傾情為你奉上編號(hào): 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)說明書 題 目: 基于TCP協(xié)議網(wǎng)上 聊天程序 系 別: 專 業(yè): 學(xué)生姓名: 學(xué) 號(hào): 指導(dǎo)教師: 2013 年 3 月 27 日專心-專注-專業(yè) 目 錄1 設(shè)計(jì)任務(wù)2 1101 設(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ù)人員所使用的基本方法和技巧?;赥CP協(xié)議網(wǎng)上聊天程序?qū)崿F(xiàn)一簡(jiǎn)單的聊天程序,實(shí)現(xiàn)網(wǎng)上聊天,包括服務(wù)器和客戶端。要求: (1)支持多人聊天。(2)客戶端具有圖形化用戶界面。1.2 聊天程序的功能客戶端使用簡(jiǎn)便,服務(wù)器端運(yùn)行穩(wěn)定

2、。客戶端與服務(wù)器端可運(yùn)行在多種系統(tǒng)平臺(tái),具有良好的兼容性能??蛻舳伺c服務(wù)器端功能獨(dú)立,可獨(dú)立運(yùn)行在不同的計(jì)算機(jī)上或運(yùn)行在同一臺(tái)計(jì)算機(jī)上,具有最大的靈活性。 根據(jù)任課教師的要求及我自己的編程能力,寫出以下的功能: 1、 登錄時(shí)只需要提供用戶名即可,無需輸入密碼。 2、 允許多人在線聊天。 3、 聊天發(fā)送的消息包括:用戶名稱、發(fā)送時(shí)間及正文。 4、 某用戶剛登錄服務(wù)器時(shí),服務(wù)器需對(duì)其發(fā)送實(shí)時(shí)在線用戶列表。 5、 某用戶登錄或退出程序時(shí)都需要給服務(wù)器發(fā)送一個(gè)消息以通知其他用戶。 6、 能夠查看聊天記錄。 2 系統(tǒng)分析2.1 系統(tǒng)理論基礎(chǔ)TCP/IP的特點(diǎn) TCP/IP協(xié)議的核心部分是傳輸層協(xié)議(TC

3、P、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í)使用的HTTP協(xié)議就是基于UDP協(xié)議的。編程時(shí),編程界面有兩種形式:一、是由內(nèi)核心直接提供的系統(tǒng)調(diào)用;二、使用以庫函數(shù)方式提供的各種函數(shù)。前者為核內(nèi)設(shè)計(jì),后者為核外設(shè)計(jì)。用戶服務(wù)要通過核外的應(yīng)用程序才能設(shè)計(jì),所以要使用套接字(socket)來設(shè)計(jì)。2.2 客戶機(jī)/服務(wù)器模式 C/S結(jié)構(gòu)(Client/Server結(jié)構(gòu))是

4、大家熟知的客戶機(jī)和服務(wù)器結(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)用發(fā)展,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)的發(fā)展方向。 首先服務(wù)器方要啟動(dòng),并根據(jù)請(qǐng)求提供相應(yīng)服務(wù): (1)打開一通道并告知本地主機(jī),它在

5、某一公認(rèn)地址端口上(如http為80)接受客戶請(qǐng)求。 (2)等待客戶請(qǐng)求到達(dá)該端口。 (3)接收到重復(fù)服務(wù)請(qǐng)求,處理該請(qǐng)求并發(fā)送應(yīng)答信號(hào)。接收并發(fā)服務(wù)請(qǐng)求,要激活一新進(jìn)程來處理這個(gè)客戶請(qǐng)求。新進(jìn)程處理此客戶請(qǐng)求,并不需要對(duì)其他請(qǐng)求做出應(yīng)答。服務(wù)完成后,關(guān)閉此新進(jìn)程與客戶的鏈路,并終止。 (4)返回第二步,等待另外的客戶請(qǐng)求 (5)關(guān)閉服務(wù)器。 客戶方: (1)打開一通道,并連接到服務(wù)器所在主機(jī)的特定端口。 (2)向服務(wù)器發(fā)出服務(wù)請(qǐng)求報(bào)文,等待并接收應(yīng)答;繼續(xù)提出請(qǐng)求。 (3)請(qǐng)求結(jié)束后關(guān)閉通道并終止。 從上面的描述過程可知: (1)客戶與服務(wù)器進(jìn)程的作用是非對(duì)稱的。因此編碼不同。 (2)服務(wù)進(jìn)

6、程一般是先于客戶請(qǐng)求啟動(dòng)的。只要系統(tǒng)運(yùn)行,該進(jìn)程一直存在,直到正常終止或者強(qiáng)迫終止。 在TCP/IP網(wǎng)絡(luò)中兩個(gè)進(jìn)程間的相互作用的主機(jī)模式是客戶機(jī)/服務(wù)器模式(Client/Server model)。該模式的建立基于以下兩點(diǎn):1、非對(duì)等作用;2、完全是異步的。客戶機(jī)/服務(wù)器模式在操作過程中采取的是主動(dòng)請(qǐng)求服務(wù)響應(yīng)的方式。2.3 Socket介紹Socket是建立在傳輸層協(xié)議(主要是TCP和UDP)上的一種套接字規(guī)范,最初是由美國(guó)加州Berkley大學(xué)提出,它定義兩臺(tái)計(jì)算機(jī)間進(jìn)行通信的規(guī)范(也是一種編程規(guī)范),如果說兩臺(tái)計(jì)算機(jī)是利用一個(gè)“通道”進(jìn)行通信,那么這個(gè)“通道”的兩端就是兩個(gè)套接字。套接

7、字屏蔽了底層通信軟件和具體操作系統(tǒng)的差異,使得任何兩臺(tái)安裝了TCP協(xié)議軟件和實(shí)現(xiàn)了套接字規(guī)范的計(jì)算機(jī)之間的通信成為可能。微軟的Windows Socket規(guī)范(簡(jiǎn)稱Winsock)對(duì)Berkley的套接字規(guī)范進(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è)SocketBind() 同服務(wù)器地址綁定 Listen() Accept()

8、block waitread()接受消息,在windows平臺(tái)中,方法為send(TCP),或者是send to(UDP)處理服務(wù)請(qǐng)求Write()發(fā)送消息,在windows平臺(tái)中,方法為send(TCP), 或者為send to(UDP)。Client方相對(duì)簡(jiǎn)單:Socket()Connect()通過一定的port連接特定的服務(wù)器,這是與服務(wù)器建立連接Write()Read()。Socket可以是基于TCP的,也可以是基于UDP,同時(shí)Socket甚至建立在其他的協(xié)議,比如IPX/SPX,DECNet等。在新建一個(gè)Socket時(shí),可以指定新建何類Socket。Bind()用來同服務(wù)器

9、的地址綁定,如果一個(gè)主機(jī)只有一個(gè)IP地址,實(shí)際上綁定的作用就相對(duì)多余了。Listen()開始監(jiān)聽網(wǎng)絡(luò),Accept()用于接受連接,其返回值是保持同客戶機(jī)聯(lián)系的Socket。在VC+ 2008中,其底層的Socket也應(yīng)該是Windows的Socket。Inprise在VC+2008中對(duì)Windows Socket進(jìn)行了有效的封裝,使得用戶可以很方便地編寫網(wǎng)絡(luò)通信程序。Socket系統(tǒng)調(diào)用包括創(chuàng)建Socket、將創(chuàng)建的Socket與本地端口綁定、建立Socket連接服務(wù)器、監(jiān)聽是否有連接、請(qǐng)求數(shù)據(jù)的可控緩沖發(fā)送和可控緩沖接收,到最后關(guān)閉Socket。首先在服務(wù)器方,利用socket()函數(shù)建立

10、流式套接字,返回套接字號(hào)s,接著利用bind()函數(shù)將套接字s與本地地址綁定,緊接著利用listen()函數(shù)通知TCP,監(jiān)聽客戶方,服務(wù)器準(zhǔn)備接收連接,沒有連接的話,服務(wù)器方通過closesocket()關(guān)閉套接字s,服務(wù)結(jié)束。有連接的話,在客戶方,通過socket()函數(shù)建立流式套接字s,此時(shí)在服務(wù)器方,建立連接,通過accept()返回,得到新的套接字ns,客戶方通過connect()將套接字s與遠(yuǎn)程地址連接,此時(shí)服務(wù)器方/客戶方在ns/s上讀/寫數(shù)據(jù),直到交換完成。交換完成后,服務(wù)器方/客戶方關(guān)閉套接字ns/s,最后服務(wù)器方通過closesocket()關(guān)閉最初套接字s,服務(wù)結(jié)束。2.4

11、系統(tǒng)開發(fā)環(huán)境本系統(tǒng)開發(fā)環(huán)境采用Visual Studio 2008。編譯語言采用C+。2.5系統(tǒng)結(jié)構(gòu)設(shè)計(jì)本系統(tǒng)采用C/S結(jié)構(gòu),最重要的特點(diǎn)是非對(duì)等相互作用,即客戶與服務(wù)器處于不平等的地位,服務(wù)器擁有客戶所不具備的硬軟件資源,客戶和服務(wù)器分別是服務(wù)的請(qǐng)求者和提供者。網(wǎng)絡(luò)中各個(gè)機(jī)器的資源是不平等的,網(wǎng)絡(luò)的真正目的就是共享這些不均等資源源,非對(duì)等相互作用特點(diǎn)也正好體現(xiàn)和適應(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ī)/服務(wù)器(C/S)體系結(jié)構(gòu),C/S結(jié)

12、構(gòu)是這樣的一種結(jié)構(gòu):它包括一個(gè)客戶機(jī)(或前端),一個(gè)服務(wù)器(或稱后端),客戶機(jī)的作用是訪問和處理遠(yuǎn)程服務(wù)器上的數(shù)據(jù),服務(wù)器的作用是接收和處理客戶機(jī)的數(shù)據(jù)請(qǐng)求。有時(shí),可能有多個(gè)客戶向同一個(gè)服務(wù)器同時(shí)請(qǐng)求服務(wù),這就需要服務(wù)器決定怎樣處理這些請(qǐng)求。Client/Server結(jié)構(gòu)是當(dāng)前數(shù)據(jù)庫應(yīng)用程序中極為流行的一種方式。尤其是網(wǎng)絡(luò)技術(shù)的發(fā)展,使得當(dāng)前很多系統(tǒng)都采用這種方式進(jìn)行構(gòu)造,其最大的優(yōu)點(diǎn)是將計(jì)算機(jī)工作任務(wù)分別由客戶端和服務(wù)器端來共同完成,這樣有利于充分合理的利用系統(tǒng)資源。另外它的服務(wù)器端還可以將信息集中起來,任何客戶機(jī)都可以通過訪問服務(wù)器而獲得所需的信息。Client/Server模型最終可歸結(jié)

13、為一種“請(qǐng)求/應(yīng)答”關(guān)系。一個(gè)請(qǐng)求總是首先被客戶發(fā)出,然后服務(wù)器總是被動(dòng)地接收請(qǐng)求,返回客戶需要的結(jié)果。在客戶發(fā)出一個(gè)請(qǐng)求之前,服務(wù)進(jìn)程一直處于休眠狀態(tài)。一個(gè)客戶提出請(qǐng)求后,服務(wù)進(jìn)程被“喚醒”并且為客戶提供服務(wù),對(duì)客戶的請(qǐng)求做出所需要的應(yīng)答。如下圖所示: 圖3.1客戶機(jī)服務(wù)器通信結(jié)構(gòu)示圖在客戶端啟動(dòng)后,客戶端計(jì)算得到本地網(wǎng)絡(luò)的廣播地址,進(jìn)行廣播查找服務(wù)器端,服務(wù)器接收到客戶端的廣播信息后返回服務(wù)器地址,則客戶端接收、驗(yàn)證信息并記錄服務(wù)器端地址,然后客戶端啟動(dòng)定時(shí)期,定時(shí)發(fā)送信息到服務(wù)器,以告知服務(wù)器自己在線,然后服務(wù)器返回在線用戶列表,服務(wù)器依靠客戶端發(fā)送的信息來更新維護(hù)在線用戶列表。在客戶端

14、與服務(wù)器盡心數(shù)據(jù)交換,擁有了在線用戶列表后,就可以選擇IP進(jìn)行客戶端之間的點(diǎn)對(duì)點(diǎn)信息交流了。如果服務(wù)器不在線,則客戶端會(huì)提示用戶退出,在一定的時(shí)間后自動(dòng)退出。3.2網(wǎng)絡(luò)通信設(shè)計(jì)在調(diào)用了Windows sockets 的啟動(dòng)函數(shù)WSACleanup()之后才能進(jìn)行其他的Socket系統(tǒng)調(diào)用,但啟動(dòng)函數(shù)WSAStartup()是為了建立與Windows Sockets DLL的連接,因此在Visual Studio 2008所建立工程的工程設(shè)置中的連接的庫模塊必須進(jìn)行設(shè)置,在其中的link欄內(nèi)的對(duì)象/庫模塊中加入“Ws2_32.lib”,才能真正建立建立與Windows Sockets DLL的連

15、接。其他的Socket系統(tǒng)調(diào)用包括創(chuàng)建Socket、將創(chuàng)建的Socket與本地端口綁定、建立Socket連接服務(wù)器、監(jiān)聽是否有連接、請(qǐng)求數(shù)據(jù)的可控緩沖發(fā)送和可控緩沖接收,到最后關(guān)閉Socket。具體流程圖如1所示。首先在服務(wù)器方,利用socket()函數(shù)建立流式套接字,返回套接字號(hào)s,接著利用bind()函數(shù)將套接字s與本地地址綁定,緊接著利用listen(0函數(shù)通知TCP,監(jiān)聽客戶方,服務(wù)器準(zhǔn)備接收連接,沒有連接的話,服務(wù)器方通過closesocket()關(guān)閉套接字s,服務(wù)結(jié)束。有連接的話,在客戶方,通過socket()函數(shù)建立流式套接字s,此時(shí)在服務(wù)器方,建立連接,通過accept()返回

16、,得到新的套接字ns,客戶方通過connect()將套接字s與遠(yuǎn)程地址連接,此時(shí)服務(wù)器方/客戶方在ns/s上讀/寫數(shù)據(jù),直到交換完成。交換完成后,服務(wù)器方/客戶方關(guān)閉套接字ns/s,最后服務(wù)器方通過closesocket()關(guān)閉最初套接字s,服務(wù)結(jié)束。具體設(shè)計(jì)過程如圖3.2所示。服務(wù)器方Socket()建立流式接字,返回套接字號(hào)s客戶方bind()套接字s與本地地址綁定listen()通知TCP服務(wù)器準(zhǔn)備接收連接accept()接收連接,等待客戶端的連接建立連接,accept()返回,得到新套接nsRecv()/send()在ns上讀/寫數(shù)據(jù),直到完成交換closesocket(),關(guān)閉套接字

17、nsclosesocket()關(guān)閉最初套接字s,服務(wù)結(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 服務(wù)器 首先運(yùn)行服務(wù)器,服務(wù)器偵聽端口消息,等待客戶端向其建立連接的申請(qǐng),一旦接收到客戶端的連接請(qǐng)求,服務(wù)器將返回一個(gè)新的套接字描述符,通過該描述符調(diào)用數(shù)據(jù)傳輸函數(shù)即可與客戶端進(jìn)行數(shù)據(jù)的收發(fā)。服務(wù)器若接收的是登陸信息,向該用戶發(fā)送在線用戶列表,并更新服務(wù)器的在線用戶列表;若收到的是發(fā)送信息

18、,服務(wù)器解析信息,然后通過廣播消息,向其所有線用戶列表發(fā)送消息。服務(wù)器端流程圖如下。 向該用戶發(fā)送在線用戶列表 開始偵聽端口消息 解析消息向其所有在線用戶發(fā)送消息首次登陸更新服務(wù)器在線用戶列表收到消息 運(yùn)行服務(wù)器 是 否 是 廣播消息 圖3.31 服務(wù)器流程圖 3.32 客戶端 在運(yùn)行服務(wù)器之后,運(yùn)行客戶端??蛻舳耸紫认蚍?wù)器提出建立連接請(qǐng)求,然后建立一個(gè)套接字描述符,通過該描述符調(diào)用數(shù)據(jù)傳輸函數(shù)即可與服務(wù)端進(jìn)行數(shù)據(jù)的收發(fā)。用戶登錄成功后,向服務(wù)器發(fā)送登陸消息,并更新本地在線用戶列表,然后通過服務(wù)器實(shí)現(xiàn)與其他客戶聊天;當(dāng)客戶退出,向服務(wù)器發(fā)送下線消息??蛻舳肆鞒虉D如下。 開始 開始 開始 運(yùn)行

19、客戶端 運(yùn)行客戶端 運(yùn)行客戶端 用戶登陸 用戶登陸 用戶登陸給服務(wù)器發(fā)送登陸消息登陸成功登陸成功向該用戶發(fā)送在線用戶列表登陸成功向該用戶發(fā)送在線用戶列表 否 是 顯示主頁面 顯示主頁面 顯示主頁面 是給服務(wù)器發(fā)送下線消息向其所有在線用戶發(fā)送消息向其所有在線用戶發(fā)送消息 是更新本地在線用戶列表更新本地在線用戶列表更新本地在線用戶列表與其他用戶進(jìn)行聊天與其他用戶進(jìn)行聊天與其他用戶進(jìn)行聊天 退出 退出 退出 圖3.32 客戶端流程圖 4 詳細(xì)設(shè)計(jì)4.1 設(shè)計(jì)服務(wù)器和客戶端的界面分別為客戶端和服務(wù)器創(chuàng)建基于對(duì)話框的MFC工程。分別為其添加顯示信息和輸入信息的文本控件和按鈕,并為其指定適當(dāng)?shù)膶傩?。服?wù)器

20、和客戶端的運(yùn)行界面分別如圖4.14.3所示。 圖4.1 服務(wù)器運(yùn)行界面設(shè)計(jì) 圖4.2 客戶端登陸界面設(shè)計(jì) 圖4.3 客戶端運(yùn)行界面設(shè)計(jì)4.2實(shí)現(xiàn)服務(wù)器和客戶端通過網(wǎng)絡(luò)通信服務(wù)器和客戶端通過定義CSocket 類的子類來重載CSocket 類中的成員函數(shù)完成服務(wù)器與客戶端之間的網(wǎng)絡(luò)通信。服務(wù)器和客戶端的交互包括客戶端登錄服務(wù)器,服務(wù)器將客戶名添加至客戶列表中,以及客戶下線后,服務(wù)器和在線客戶將下線客戶從客戶列表中刪除等。4.3實(shí)現(xiàn)多個(gè)客戶端之間的實(shí)時(shí)聊天功能 由于客戶端/服務(wù)器模式,客戶在進(jìn)行聊天時(shí),需要把待發(fā)送的消息發(fā)送至服務(wù)器;服務(wù)器接收到消息后,經(jīng)過查詢客戶列表,尋找接受的客戶名后,將消息

21、轉(zhuǎn)發(fā)至在線客戶處。由于服務(wù)器與客戶端交互時(shí),還需接收客戶端的登錄信息,故將接收客戶端的登錄信息和接收消息發(fā)在同一個(gè)接收函數(shù)中。 根據(jù)以上步驟,對(duì)實(shí)現(xiàn)聊天工具的服務(wù)器和客戶端的關(guān)鍵代碼解說如下。 (1)服務(wù)器初始化,開始監(jiān)聽客戶端的連接請(qǐng)求,具體代碼如下:BOOL CChatServerApp:InitInstance()if (!AfxSocketInit() /套接字初始化失敗AfxMessageBox(IDP_SOCKETS_INIT_FAILED);return FALSE;AfxEnableControlContainer();CServerSocket *m_pSocket; /自定

22、義的CSocket類的子類 m_pSocket = new CServerSocket;if(!m_pSocket->Create(9999) /創(chuàng)建套接字AfxMessageBox(_T("創(chuàng)建Socket失??!");return FALSE;if(!m_pSocket->Listen() /監(jiān)聽客戶端的連接請(qǐng)求AfxMessageBox(_T("創(chuàng)建偵聽發(fā)生錯(cuò)誤!");return FALSE;(2)客戶端登陸至服務(wù)器,具體代碼如下: void CLoginDlg:OnOK() UpdateData(); /獲取文本框中數(shù)據(jù)if(!m_p

23、Socket->Create() /創(chuàng)建套接字AfxMessageBox(_T("網(wǎng)絡(luò)創(chuàng)建錯(cuò)誤!");m_pSocket->Close();return;if(!m_pSocket->Connect(m_strServer,9999) /連接至服務(wù)器AfxMessageBox(_T("連接服務(wù)器失?。?quot;);m_pSocket->Close();return;Header head;head.type = LOGIN_IO;head.len = m_strName.GetLength();m_pSocket->Send(cha

24、r *)&head,sizeof(Header); /發(fā)送客戶信息至服務(wù)器m_pSocket->Send(m_strName,m_strName.GetLength();theApp.m_strName = m_strName;CDialog:OnOK(); (3)服務(wù)器接收新登錄客戶的信息,具體代碼如下:void CClientSocket:OnReceive(int nErrorCode) char buff1sizeof(Header);memset(buff1, 0, sizeof(buff1);Receive(buff1,sizeof(buff1);Header *he

25、ader = (Header*)buff1;int length = header->len;char type = header->type;if(type = LOGIN_IO) /如果收到的是登錄信息char buff1000; memset(buff,0,sizeof(buff); Receive(buff,length); /接受客戶登錄信息CTime time = CTime:GetCurrentTime(); /獲取當(dāng)前系統(tǒng)時(shí)間 CString t = time.Format("%Y-%m-%d %H:%M:%S"); /時(shí)間格式CEdit *p_

26、Edit = (CEdit *):AfxGetMainWnd()->GetDlgItem(IDC_EDIT_INFO);CString strTemp = t + ": " + CString(buff) + " 進(jìn)入rn" /顯示登錄信息p_Edit->ReplaceSel(strTemp); /更新在線客戶列表 m_strName = buff; m_dlgServer->UpdateUser(this);if(type = SEND_MESSAGE) /如果接受的是客戶發(fā)送信息char buff1000; memset(buff,

27、0,sizeof(buff); Receive(buff,sizeof(buff); /接收消息內(nèi)容CClientSocket *curr = NULL;POSITION pos = clist->GetHeadPosition();while (pos != NULL) /將消息發(fā)至在線客戶curr = (CClientSocket *)clist->GetNext(pos);curr->Send(char *)header,sizeof(Header);curr->Send(buff, sizeof(buff);CSocket:OnReceive(nErrorCod

28、e); (4)客戶發(fā)送消息,先將消息發(fā)至服務(wù)器,具體代碼如下:void CMyChatDlg:OnSend() UpdateData();if(m_strMessage = "")AfxMessageBox(_T("不能發(fā)送空消息!");CEdit *pEdit = (CEdit*)GetDlgItem(IDC_EDIT_MESSAGE);pEdit->SetFocus();return;Header head;head.type = SEND_MESSAGE;head.len = m_strMessage.GetLength();CTime ti

29、me = CTime:GetCurrentTime();CString t = time.Format("%H:%M:%S");CString nikeName = theApp.m_strName;CString str = nikeName + " " + t + "rn" + " " +m_strMessage;m_pSocket->Send(char *)&head,sizeof(Header); /將發(fā)送時(shí)間和收信客戶信息發(fā)至服務(wù)器if(m_pSocket->Send(LPCTSTR)

30、str, str.GetLength() /發(fā)送信息內(nèi)容m_strMessage = ""UpdateData(FALSE);CEdit *pEdit = (CEdit*)GetDlgItem(IDC_EDIT_MESSAGE);pEdit->SetFocus();elseAfxMessageBox(_T("網(wǎng)絡(luò)傳輸錯(cuò)誤!"); (5)服務(wù)器接收消息并轉(zhuǎn)發(fā),具體代碼如下:void CClientSocket:OnReceive(int nErrorCode) char buff1sizeof(Header);memset(buff1, 0, siz

31、eof(buff1);Receive(buff1,sizeof(buff1);Header *header = (Header*)buff1;int length = header->len;char type = header->type;if(type = LOGIN_IO) /如果收到的是登錄信息char buff1000; memset(buff,0,sizeof(buff); Receive(buff,length); /接受客戶登錄信息CTime time = CTime:GetCurrentTime(); /獲取當(dāng)前系統(tǒng)時(shí)間 CString t = time.Form

32、at("%Y-%m-%d %H:%M:%S"); /時(shí)間格式CEdit *p_Edit = (CEdit *):AfxGetMainWnd()->GetDlgItem(IDC_EDIT_INFO);CString strTemp = t + ": " + CString(buff) + " 進(jìn)入rn" /顯示登錄信息p_Edit->ReplaceSel(strTemp); /更新在線客戶列表 m_strName = buff; m_dlgServer->UpdateUser(this);if(type = SEND_

33、MESSAGE) /如果接受的是客戶發(fā)送信息char buff1000; memset(buff,0,sizeof(buff); Receive(buff,sizeof(buff); /接收消息內(nèi)容CClientSocket *curr = NULL;POSITION pos = clist->GetHeadPosition();while (pos != NULL) /將消息發(fā)至在線客戶curr = (CClientSocket *)clist->GetNext(pos);curr->Send(char *)header,sizeof(Header);curr->Se

34、nd(buff, sizeof(buff);CSocket:OnReceive(nErrorCode); (6)客戶端接收服務(wù)器轉(zhuǎn)發(fā)的消息,具體代碼如下: BOOL CMyChatDlg:GetMessage() /接受服務(wù)器轉(zhuǎn)發(fā)的信息char buff1000;memset(buff,0,sizeof(buff);m_pSocket->Receive(buff, sizeof(buff),0);CString strTemp = buff;strTemp += _T("rn");m_MessageList.ReplaceSel(strTemp); /顯示接受到的信息

35、return TRUE; (7)客戶下線后,服務(wù)器將下線的客戶從客戶列表中刪除,具體代碼如下: void CClientSocket:OnClose(int nErrorCode) /服務(wù)器通過失去連接錯(cuò)誤碼獲知下線的客戶POSITION pos = clist->Find(this);if(pos != NULL)clist->RemoveAt(pos); /將下線客戶信息從列表中刪除CTime time = CTime:GetCurrentTime();CString t = time.Format("%Y-%m-%d %H:%M:%S");CEdit *p

36、_Edit = (CEdit *)m_dlgServer->GetDlgItem(IDC_EDIT_INFO);CString strTemp = t + ": " + this->m_strName + " 離開rn"p_Edit->ReplaceSel(strTemp); /顯示客戶下線信息m_dlgServer->UpdateUser(this);this->Close(); /關(guān)閉與下線客戶連接的套接字delete this;CSocket:OnClose(nErrorCode); (8)其他客戶下線后,客戶端更新在

37、線用戶列表,具體代碼如下:void CMyChatDlg:UpdateUser()char buff1000;memset(buff,0,sizeof(buff);m_pSocket->Receive(buff, sizeof(buff),0); /接收用戶下線信息CString user_info = buff;CString array100;int b = 0;for( int i=0; i<user_info.GetLength(); i+ ) /查找當(dāng)前在線用戶if(i != (user_info.GetLength() - 1)if ( user_infoi='

38、&' )b +;elsearrayb = arrayb + user_infoi;m_UserList.ResetContent();for(int j=0; j<b+1; j+) /更新在線用戶列表m_UserList.AddString(arrayj);5總結(jié) 經(jīng)過了整整3個(gè)星期的忙碌,終于完成了課程設(shè)計(jì)。在這段時(shí)間里體驗(yàn)了無數(shù)的酸甜苦辣,從解決不了細(xì)小問題的苦惱到問題最終解決的喜悅。一直伴隨著整個(gè)設(shè)計(jì)過程。整個(gè)設(shè)計(jì)過程是不斷學(xué)習(xí),不斷發(fā)現(xiàn)問題、分析問題、解決問題的過程。使我受益良多。設(shè)計(jì)期間有許多的感觸、想法、經(jīng)驗(yàn)、教訓(xùn),對(duì)以后的學(xué)習(xí)、工作有很大的益處。 這次的課程設(shè)計(jì)是簡(jiǎn)單聊天程序,在平日的生活學(xué)習(xí)中,可以說QQ

溫馨提示

  • 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ì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論