畢業(yè)設(shè)計(jì)---局域網(wǎng)即時(shí)通信軟件設(shè)計(jì)_第1頁
已閱讀1頁,還剩38頁未讀 繼續(xù)免費(fèi)閱讀

下載本文檔

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

文檔簡介

1、<p>  局域網(wǎng)即時(shí)通信軟件設(shè)計(jì)</p><p>  畢業(yè)論文(設(shè)計(jì))任務(wù)書</p><p><b>  院(系):文經(jīng)學(xué)院</b></p><p>  [摘 要] 即時(shí)通信在互聯(lián)網(wǎng)領(lǐng)域的應(yīng)用取得了巨大的成功,但是在學(xué)校、企業(yè)內(nèi)部的應(yīng)用仍遠(yuǎn)未普及。鑒于即時(shí)通信作為一項(xiàng)有廣泛應(yīng)用價(jià)值的技術(shù)框架,在逐步適應(yīng)企業(yè)網(wǎng)絡(luò)、教育網(wǎng)絡(luò)的應(yīng)用特點(diǎn)

2、后,局域網(wǎng)即時(shí)通信必將取得和電子郵件一樣的普及效果。該系統(tǒng)使用.NET作為開發(fā)平臺(tái)、Mysql數(shù)據(jù)庫存儲(chǔ)用戶信息和聊天記錄,用套接字連接客戶端和服務(wù)器,用數(shù)據(jù)包套接字發(fā)送消息。本系統(tǒng)采用C/S模式構(gòu)建,由客戶端和服務(wù)器端組成??蛻舳酥灰顚懛?wù)器的IP地址和通信端口號(hào),并通過所分配的賬號(hào),就可以登錄和使用。服務(wù)器與Mysql數(shù)據(jù)庫可部署在同一網(wǎng)段的任一節(jié)點(diǎn)上,通過接收客戶端不同請(qǐng)求而對(duì)數(shù)據(jù)庫進(jìn)行增刪改查的操作,這樣就可以方便的進(jìn)行維護(hù)并

3、且保證了同一局域網(wǎng)信息的安全和網(wǎng)絡(luò)資源的充分利用,并且最大程度的保證了數(shù)據(jù)庫的安全性。使用該系統(tǒng)可進(jìn)行一般的文字交流,查詢聊天記錄,及在線用戶顯示等功能。</p><p>  [關(guān)鍵詞] .NET Framework;Socket;多線程;Mysql數(shù)據(jù)庫;TCP/IP協(xié)議;ADO.NET</p><p>  [Abstract] Instant messaging application

4、s on the Internet were a great success, but in schools, enterprises are still far from universal in application. In view of instant messaging applications as the value of a broad technical framework, and gradually adapt

5、to the corporate network, the application of the characteristics of the education network, the LAN access to instant messaging and e-mail will be the same universal effect.The introduction of the system. NET as a develop

6、ment platform, Mysql</p><p>  This can be convenient for maintenance and to ensure that the same local area network information security and make full use of network resources and ensure maximum safety of th

7、e database. The system can be used for general exchange of text, query chats, and online user functions.</p><p>  [Key words] .NET Framework; Socket; Thread; Mysql Database; TCP/IP; ADO.NET</p><p&

8、gt;<b>  目 錄</b></p><p><b>  前言1</b></p><p>  1.課題及開發(fā)平臺(tái)簡介1</p><p>  1.1 課題介紹1</p><p>  1.2 開發(fā)平臺(tái)簡介1</p><p>  1.3 編程語言簡介(C#)2

9、</p><p>  1.4主要設(shè)計(jì)功能4</p><p>  2.數(shù)據(jù)庫設(shè)計(jì)及基本實(shí)現(xiàn)原理5</p><p>  2.1 數(shù)據(jù)庫設(shè)計(jì)5</p><p>  2.1.1 class表簡介5</p><p>  2.1.2 user表簡介5</p><p>  2.1.2 chatlog

10、表簡介6</p><p>  2.2 基本實(shí)現(xiàn)原理7</p><p>  2.2.1 WINSOCK接口7</p><p>  2.2.2客戶機(jī)/服務(wù)器模式7</p><p>  2.3 二者的結(jié)合(DBA)8</p><p>  3.客戶端編程實(shí)現(xiàn)10</p><p>  3.1

11、用戶登陸功能10</p><p>  3.1.1 連接服務(wù)器11</p><p>  3.1.2 開啟新線程用于接收服務(wù)器發(fā)回的消息11</p><p>  3.1.3 向服務(wù)器發(fā)送用戶名與密碼信息11</p><p>  3.2 接收服務(wù)器發(fā)回的指令12</p><p>  3.2.1 接收發(fā)回的原始消息并

12、還原12</p><p>  3.2.2 分析處理服務(wù)器發(fā)回的指令12</p><p>  3.3 登陸后界面初始化12</p><p>  3.3.1 驗(yàn)證成功與進(jìn)入主界面12</p><p>  3.3.2 初始化用戶列表13</p><p>  3.3.3 顯示在線用戶15</p>&l

13、t;p>  3.4 聊天功能16</p><p>  3.4.1 發(fā)送消息16</p><p>  3.4.2 接收消息18</p><p>  3.5 查詢聊天記錄功能19</p><p>  3.6 用戶離線22</p><p>  3.6.1 發(fā)送離線請(qǐng)求22</p><p&

14、gt;  3.6.2 接收用戶離線消息22</p><p>  3.7 報(bào)錯(cuò)功能23</p><p>  4.服務(wù)器端編程實(shí)現(xiàn)24</p><p>  4.1 啟動(dòng)服務(wù)24</p><p>  4.1.1 聲明變量24</p><p>  4.1.2 顯示服務(wù)器IP24</p><p&g

15、t;  4.1.3 啟動(dòng)服務(wù)24</p><p>  4.1.4 監(jiān)聽客戶端請(qǐng)求25</p><p>  4.2 接收客戶端請(qǐng)求26</p><p>  4.3 根據(jù)客戶端不同請(qǐng)求做出操作26</p><p>  4.3.1 連接請(qǐng)求27</p><p>  4.3.2 即時(shí)聊天請(qǐng)求29</p>

16、<p>  4.3.3 查詢聊天記錄請(qǐng)求30</p><p>  4.3.4 用戶離線請(qǐng)求30</p><p>  4.4 即時(shí)發(fā)送“錯(cuò)誤”指令31</p><p><b>  5.結(jié)論32</b></p><p><b>  6.致謝33</b></p>&l

17、t;p><b>  參考文獻(xiàn)34</b></p><p><b>  前言</b></p><p>  由于因特網(wǎng)的迅速流行,越來越多的應(yīng)用程序具備了在網(wǎng)上與其它程序通信的能力。從WIN95開始微軟把網(wǎng)絡(luò)功能融進(jìn)了它的操作系統(tǒng),使得應(yīng)用程序網(wǎng)絡(luò)通信能力更為普及。因此,微軟的TCP/IP協(xié)議也就成為網(wǎng)絡(luò)應(yīng)用程序基于的首選協(xié)議。</p&

18、gt;<p>  一般采用TCP/IP協(xié)議的應(yīng)用程序只實(shí)現(xiàn)了單用戶與服務(wù)器間點(diǎn)對(duì)點(diǎn)的連接,而本文在VC6.0的環(huán)境下,運(yùn)用了了多線程以及共享數(shù)據(jù)結(jié)構(gòu)技術(shù),不僅實(shí)現(xiàn)了多用戶與服務(wù)器間的連接,而且解決了多用戶間信息互發(fā)問題----依靠服務(wù)器的轉(zhuǎn)發(fā)功能。并且,數(shù)據(jù)庫技術(shù)的引入,使得大數(shù)據(jù)保存成為了可能,并可在任意客戶端查詢聊天記錄。</p><p>  借助微軟Visual Studio2008 .NET

19、開發(fā)平臺(tái),與其自帶的ADO.NET組件,使開發(fā)效率大大提速。</p><p>  1.課題及開發(fā)平臺(tái)簡介</p><p><b>  1.1 課題介紹</b></p><p>  局域網(wǎng)即時(shí)通信,不同于大家熟知的MSN這樣的基于互聯(lián)網(wǎng)的即時(shí)通信,而是基于學(xué)校教育網(wǎng)、企業(yè)內(nèi)部局域網(wǎng)使用的即時(shí)通信。</p><p>  即時(shí)

20、通信在互聯(lián)網(wǎng)領(lǐng)域的應(yīng)用取得了巨大的成功,但是在學(xué)校、企業(yè)等內(nèi)部網(wǎng)絡(luò)的應(yīng)用仍遠(yuǎn)未普及。傳輸速度、總體投入及廣域網(wǎng)無法比肩的安全性,注定了局域網(wǎng)層出不窮的潛力,在學(xué)校、企業(yè)內(nèi)部更是如此。在這種前提下,一款可以即時(shí)收發(fā)消息用來收發(fā)通知,可查詢歷史消息的通信軟件的需求成為了必然。正是在這種前提下,結(jié)合實(shí)際情況,我決定開發(fā)一套局域網(wǎng)即時(shí)通信軟件設(shè)計(jì)軟件。</p><p>  1.2 開發(fā)平臺(tái)簡介</p>&l

21、t;p>  .NET Framework 是微軟的幾個(gè)開發(fā)團(tuán)隊(duì)一起努力發(fā)展的成果,最主要用來產(chǎn)生一個(gè)可以用來快速開發(fā)、部署網(wǎng)站服務(wù)及應(yīng)用程序的開發(fā)平臺(tái)。作為微軟公司繼WindowsDNA以來的新的開發(fā)平臺(tái)。.Net Framework是以一種類似于Java系統(tǒng)的虛擬機(jī)方式運(yùn)行和管理的編程平臺(tái),通過CLR為基礎(chǔ),支持多種語言(C#、VB.NET、C++、Python等)的開發(fā)。</p><p>  C#是一種

22、安全的、穩(wěn)定的、簡單的,由C和C++衍生出來的面向?qū)ο蟮木幊陶Z言。它在繼承C和C++強(qiáng)大功能的同時(shí)去掉了一些它們的復(fù)雜特性(例如沒有宏和模版,不允許</p><p>  多重繼承)。C#綜合了VB簡單的可視化操作和C++的高運(yùn)行效率,以其強(qiáng)大的操作能力、優(yōu)雅的語法風(fēng)格、創(chuàng)新的語言特性和便捷的面向組件編程的支持成為.NET開發(fā)的首選語言。</p><p>  在Visual Studio 2

23、008的C++語言當(dāng)中,MFC可以支持Vista的通用控件。Visual Studio 2008還支持智能感應(yīng),除此以外,對(duì)于AJAX引入了很多擴(kuò)展控件,從而可以快速開發(fā)ASP.NET AJAX的應(yīng)用。新的Vista SDK中包含大量的非托管API。UAC(用戶訪問控制)是Vista的一種訪問控制機(jī)制,主要是防止病毒對(duì)系統(tǒng)的破壞。</p><p>  使用Visual Studio 2008可以高效開發(fā)Windo

24、ws應(yīng)用。設(shè)計(jì)器中可以實(shí)時(shí)反映變更,XAML中智能感知功能可以提高開發(fā)效率。同時(shí)Visual Studio 2008支持項(xiàng)目模板、調(diào)試器和部署程序。使用Expression交互式設(shè)計(jì)器可以無縫集成設(shè)計(jì)人員與開發(fā)人員的工作流程。</p><p>  LINQ是一種用來進(jìn)行數(shù)據(jù)訪問的編程模型,使得.NET語言可以直接支持?jǐn)?shù)據(jù)查詢。LINQ的目標(biāo)是降低訪問數(shù)據(jù)的復(fù)雜度。LINQ可以用統(tǒng)一的方法訪問不同類型的數(shù)據(jù),可以將

25、數(shù)據(jù)作為對(duì)象使用,能夠更好地與編程模型集成,可以在Visual Studio 中進(jìn)行智能提示。</p><p>  1.3 編程語言簡介(C#)</p><p>  1.面向?qū)ο蟮目梢暬幊谭椒ǎ?lt;/p><p>  用傳統(tǒng)程序設(shè)計(jì)語言設(shè)計(jì)程序時(shí),大都是通過編寫程序代碼來實(shí)現(xiàn)用戶界面,在設(shè)計(jì)過程中看不到界面的實(shí)際顯示效果,必須編譯后運(yùn)行程序才能觀察,這很麻煩,大大影

26、響了軟件開發(fā)的效率。C#則是應(yīng)用的面向?qū)ο蟮某绦蛟O(shè)計(jì)方法(OOP),提供了可視化的設(shè)計(jì)方法,它把程序和數(shù)據(jù)封裝起來作為一個(gè)對(duì)象,并為每個(gè)對(duì)象賦予應(yīng)有的屬性,使對(duì)象成為實(shí)在的東西。開發(fā)人員不必再為界面設(shè)計(jì)而編寫大量程序代碼,也不需要通過一遍遍編譯來修改不滿意之處了。只要按設(shè)計(jì)要求的屏幕布局,用系統(tǒng)提供的工具,在屏幕上畫出各種“部件”,即圖形對(duì)象,并設(shè)置這些圖形對(duì)象的屬性,就可以輕松完成任務(wù)了。C#會(huì)自動(dòng)產(chǎn)生界面設(shè)計(jì)代碼,程序設(shè)計(jì)人員不必再

27、手工編寫實(shí)現(xiàn)程序功能的那些煩人的代碼,從而可以大大提高程序設(shè)計(jì)的效率。</p><p>  2.結(jié)構(gòu)化程序設(shè)計(jì)語言:</p><p>  C#是在C/C++語言的基礎(chǔ)上發(fā)展起來的,具有高級(jí)程序設(shè)計(jì)語言的語句結(jié)構(gòu),接近于自然語言和人類的邏輯思維方式。C#語句簡單易懂,其編輯器支持彩色代碼,可自動(dòng)進(jìn)行語法錯(cuò)誤檢查,同時(shí)具有功能強(qiáng)大且使用靈活的調(diào)試器和編譯器。</p><p&

28、gt;  C#是面向?qū)ο笮驼Z言,在輸入代碼的同時(shí),解釋系統(tǒng)將高級(jí)語言分解翻譯成計(jì)算機(jī)可以識(shí)別的機(jī)器指令,并判斷每個(gè)語句的語法錯(cuò)誤。在設(shè)計(jì)C#程序的過程中,隨時(shí)可以運(yùn)行程序,而在整個(gè)程序設(shè)計(jì)好之后,可以編譯生成可執(zhí)行文件(.EXE),脫離C#環(huán)境,直接在Windows環(huán)境下運(yùn)行。</p><p>  3.事件驅(qū)動(dòng)編程機(jī)制:</p><p>  C#通過事件來執(zhí)行對(duì)象的操作。一個(gè)對(duì)象可能會(huì)產(chǎn)生

29、多個(gè)事件,每個(gè)事件都可以通過一段程序來響應(yīng)。例如,命令按鈕是一個(gè)對(duì)象,當(dāng)用戶單擊該按鈕時(shí),將產(chǎn)生一個(gè)“單擊”(CLICK)事件,而在產(chǎn)生該事件時(shí)將執(zhí)行一段程序,用來實(shí)現(xiàn)指定的操作。</p><p>  在用C#設(shè)計(jì)大型應(yīng)用軟件時(shí),不必建立具有明顯開始和結(jié)束的程序,而是編寫若干個(gè)微小的子程序,即過程。這些過程分別面向不同的對(duì)象,由用戶操作引發(fā)某個(gè)事件來驅(qū)動(dòng)完成某種特定的功能,或者由事件驅(qū)動(dòng)程序調(diào)用通用過程來執(zhí)行指定

30、的操作,這樣可以方便編程人員,提高效率。</p><p>  4.訪問數(shù)據(jù)庫功能:</p><p>  C#具有強(qiáng)大的數(shù)據(jù)庫管理功能,利用數(shù)據(jù)控件和數(shù)據(jù)庫管理窗口,可以直接建立或處理Microsoft SQL Server 2005 Express格式的數(shù)據(jù)庫,并提供了強(qiáng)大的數(shù)據(jù)存儲(chǔ)和檢索功能。同時(shí),C#還能直接編輯和訪問其他外部數(shù)據(jù)庫,如:DATABASE,F(xiàn)oxPro,Paradox等

31、,這些數(shù)據(jù)庫格式都可以用C# 編輯和處理。</p><p>  C#提供開放式數(shù)據(jù)連接,即ADO.NET功能,可通過直接訪問或建立連接的方式使用并操作后臺(tái)大型網(wǎng)絡(luò)數(shù)據(jù)庫,如SQL Server,Oracle等。在應(yīng)用程序中,可以使用結(jié)構(gòu)化查詢語言SQL數(shù)據(jù)標(biāo)準(zhǔn),直接訪問服務(wù)器上的數(shù)據(jù)庫,還提供了簡單的面向?qū)ο蟮膸觳僮髦噶詈投嘤脩魯?shù)據(jù)庫訪問的加鎖機(jī)制和網(wǎng)絡(luò)數(shù)據(jù)庫的SQL的編程技術(shù),為單機(jī)上運(yùn)行的數(shù)據(jù)庫提供了SQL網(wǎng)

32、絡(luò)接口,可以在分布式環(huán)境中快速而有效地實(shí)現(xiàn)客戶/服務(wù)器(client/server)方案。</p><p>  5.動(dòng)態(tài)數(shù)據(jù)交換(DDE)功能:</p><p>  利用動(dòng)態(tài)數(shù)據(jù)交換(Dynamic Data Exchange)技術(shù),可以把一種應(yīng)用程序中的數(shù)據(jù)動(dòng)態(tài)地鏈接到另一種應(yīng)用程序中,使兩種完全不同的應(yīng)用程序建立起一條動(dòng)態(tài)數(shù)據(jù)鏈路。當(dāng)原始數(shù)據(jù)變化時(shí),可以自動(dòng)更新鏈接的數(shù)據(jù)。C#提供了動(dòng)

33、態(tài)數(shù)據(jù)交換的編程技術(shù),可以在應(yīng)用程序中與其他Windows應(yīng)用程序建立動(dòng)態(tài)數(shù)據(jù)交換,在不同的應(yīng)用程序之間進(jìn)行通信。</p><p>  6.對(duì)象的鏈接與嵌入(OLE)功能:</p><p>  對(duì)象的鏈接與嵌入(OLE)將每個(gè)應(yīng)用程序都看作是一個(gè)對(duì)象(object),將不同的對(duì)象鏈接(link)起來,再嵌入(embed)某個(gè)應(yīng)用程序中,從而可以得到具有聲音、影像、圖像、動(dòng)畫、文字等各種信息

34、的集合式的文件。利用OLE技術(shù),可以方便地建立復(fù)合式文檔(compound document),這種文檔由來自多個(gè)不同應(yīng)用程序的對(duì)象組成,文檔中的每個(gè)對(duì)象都與原來的應(yīng)用程序相聯(lián)系,并可執(zhí)行與原來應(yīng)用程序完全相同的操作。Visual Basic就采用了OLE技術(shù)。</p><p>  7.動(dòng)態(tài)鏈接庫(DLL)功能:</p><p>  C# 是一種高級(jí)程序設(shè)計(jì)語言,不具備低級(jí)語言的功能,對(duì)訪

35、問機(jī)器硬件的操作不太容易實(shí)現(xiàn)。但它可以通過動(dòng)態(tài)鏈接庫技術(shù)將C/C++或匯編語言編寫的程序加入到C# 應(yīng)用程序中,可以像調(diào)用內(nèi)部函數(shù)一樣調(diào)用其他語言編寫的函數(shù)。此外,通過動(dòng)態(tài)鏈接庫,還可以調(diào)用Windows應(yīng)用程序接口(API)函數(shù),實(shí)現(xiàn)SDK所具有的功能。</p><p><b>  1.4主要設(shè)計(jì)功能</b></p><p>  本程序需要具備以下功能:</p

36、><p><b>  用戶密碼驗(yàn)證功能;</b></p><p>  與在線用戶進(jìn)行即時(shí)通信交流;</p><p>  保存與離線好友交流文字信息功能;</p><p>  顯示所有好友在線和離線功能;</p><p><b>  查詢聊天記錄功能;</b></p>

37、<p>  2.數(shù)據(jù)庫設(shè)計(jì)及基本實(shí)現(xiàn)原理</p><p><b>  2.1 數(shù)據(jù)庫設(shè)計(jì)</b></p><p>  在Mysql中建立名稱為client的數(shù)據(jù)庫,并在此數(shù)據(jù)庫中創(chuàng)建chatlog、class、user三個(gè)數(shù)據(jù)表分別用來存放聊天記錄、存放班級(jí)信息和存放用戶信息。</p><p>  以下為對(duì)各個(gè)數(shù)據(jù)表的詳細(xì)說明。&l

38、t;/p><p>  2.1.1 class表簡介</p><p>  class數(shù)據(jù)表設(shè)計(jì)視圖如表2-1所示:</p><p>  表2-1 class表</p><p>  如上表所示,class表共有classBM、classNAME兩個(gè)字段,分別存放班級(jí)編碼和班級(jí)名稱,并且必須一一對(duì)應(yīng)。在設(shè)計(jì)程序中的好友列表中,作為所有學(xué)生的根節(jié)點(diǎn)。在好

39、友列表顯示時(shí),可根據(jù)學(xué)生所屬班級(jí)進(jìn)行方便快速的查找。所有學(xué)生必須只屬于一個(gè)班級(jí)編碼下,否則不能正常顯示。此表由服務(wù)器所在電腦維護(hù)。</p><p>  2.1.2 user表簡介</p><p>  user數(shù)據(jù)表設(shè)計(jì)視圖如表2-2所示:</p><p>  表2-2 user表</p><p>  user表共有id、name、passwo

40、rd、classBM四個(gè)字段,分表用來存放用戶id、姓名、密碼、班級(jí)代碼。</p><p>  id字段為此數(shù)據(jù)表主鍵,不允許重復(fù),作為用戶的唯一標(biāo)示。可自動(dòng)生成。</p><p>  name字段為學(xué)生的姓名信息,可通過它登錄系統(tǒng)。</p><p>  password字段為此用戶的密碼,最多可維護(hù)進(jìn)15個(gè)字符。在系統(tǒng)登錄時(shí),填寫的姓名與密碼必須同時(shí)驗(yàn)證成功才能正

41、確的登錄系統(tǒng)。</p><p>  classBM字段為學(xué)生所屬班級(jí)代碼,每條學(xué)生信息必須維護(hù)此字段,否則無法在用戶列表中正確顯示。</p><p>  2.1.2 chatlog表簡介</p><p>  chatlog表視圖如表2-3所示:</p><p>  表2-3 chatlog表</p><p>  cha

42、tlog表共有FROMUSER、TOUSER、DATETIMEN、LOGS四字段,分表存放聊天記錄的發(fā)送方、接收方、時(shí)間、內(nèi)容。</p><p>  FROMUSER字段為聊天記錄發(fā)送方姓名,與表2中name字段外鍵關(guān)系,所以必須為user中用戶名稱一致。</p><p>  TOUSER字段為聊天記錄接收方姓名,與表2中name字段外鍵關(guān)系,所以必須為user中用戶名稱一致。</p

43、><p>  DATETIMEN字段為聊天記錄在服務(wù)器中轉(zhuǎn)的時(shí)間(精確到毫秒),此字段與FROMUSER、TOUSER字段共同作為此表的主鍵,保證了每條記錄主鍵不沖突。</p><p>  LOGS此字段用以存放聊天記錄,字段數(shù)據(jù)類型為TEXT,所以可輕松用于可進(jìn)行大數(shù)據(jù)編輯。</p><p>  2.2 基本實(shí)現(xiàn)原理</p><p>  2.2

44、.1 WINSOCK接口</p><p>  WINSOCK標(biāo)準(zhǔn)定義了一個(gè)DLL接口,通常叫做WINSOCK.DLL或者WSOCK32.DLL。無論機(jī)器上安裝了哪一個(gè)DLL,只要函數(shù)的名字,參數(shù)含義以及最終的功能是相同的,應(yīng)用程序就可以調(diào)用這些函數(shù)。在插口編程里一個(gè)重要的概念就是一個(gè)插口的端口。局域網(wǎng)內(nèi)的每一個(gè)站點(diǎn)都有一個(gè)數(shù)字地址稱為IP地址,通常是由“.”分開的四個(gè)數(shù)。在機(jī)器上運(yùn)行的程序可以隨心所欲地用端口與其

45、他機(jī)器進(jìn)行通信。多數(shù)端口的工作是基于連接的:兩個(gè)程序在每一端用一個(gè)端口形成一個(gè)連接,然后沿著該連接收發(fā)數(shù)據(jù)。有些應(yīng)用程序傾向無連接地發(fā)送,但是這些數(shù)據(jù)的到達(dá)是沒有保障的。 WINSOCK.DLL實(shí)際上是作為WinSock應(yīng)用程序和TCP/IP協(xié)議棧之間的中間層。用戶的應(yīng)用程序告訴WINSOCK.DLL需要做什么,WINSOCK.DLL將這些命令傳送到TCP/IP協(xié)議棧,由TCP/IP協(xié)議棧傳送到網(wǎng)絡(luò)。但是重要的事情是用戶必須注意

46、用戶使用的WINSOCK.DLL必須和TCP/IP的版本號(hào)一致。</p><p>  2.2.2客戶機(jī)/服務(wù)器模式</p><p>  由于Winsock支持多種協(xié)議上的網(wǎng)絡(luò)程序開發(fā), 比如TCP、UDP、和IP等等。由于這次課程設(shè)計(jì)是實(shí)現(xiàn)點(diǎn)到點(diǎn)的可靠連接,所以在此使用TCP連接方式。在這個(gè)連接中,雙方分為客戶和服務(wù)器,他們各自的功能不同。</p><p>  客戶

47、機(jī)一方,TCP/IP應(yīng)用程序功能如下:</p><p>  (1) 打開通信信道(申請(qǐng)一套接字),并連接到服務(wù)器在主機(jī)的保留端口,該端口對(duì)應(yīng)服務(wù)器的TCP/IP進(jìn)程。</p><p> ?。?) 向服務(wù)器發(fā)出請(qǐng)求報(bào)文,等待接收應(yīng)答。</p><p>  (3) 從服務(wù)器方收到最終應(yīng)答結(jié)果,或在不再請(qǐng)求時(shí)關(guān)閉信道并終止客戶機(jī)進(jìn)程。</p><p&g

48、t;  服務(wù)器一方,TCP/IP應(yīng)用程序動(dòng)作如下:</p><p> ?。?) 打開通信信道(申請(qǐng)一套接字),通知本地主機(jī)在某一保留端口接收客戶機(jī)請(qǐng)求。</p><p> ?。?) 等待客戶請(qǐng)求到達(dá)指定端口。</p><p> ?。?) 接收到請(qǐng)求,啟動(dòng)一新進(jìn)程處理用戶請(qǐng)求,同時(shí)釋放舊進(jìn)程以響應(yīng)新的客戶請(qǐng)求,一旦服務(wù)完成,關(guān)閉新進(jìn)程與客戶的通信鏈路。</p&g

49、t;<p> ?。?) 繼續(xù)等待客戶機(jī)請(qǐng)求。</p><p>  (5) 如果不想響應(yīng)客戶機(jī)請(qǐng)求,關(guān)閉服務(wù)器進(jìn)程。</p><p>  綜上所述,TCP/IP應(yīng)用中的服務(wù)器程序必須先于客戶機(jī)進(jìn)程啟動(dòng),直到對(duì)客戶機(jī)的響應(yīng)結(jié)束或強(qiáng)迫終止。其面向連接的應(yīng)用程序流程圖如圖2-1。</p><p>  圖2-1 C/S模式</p><p>

50、;  2.3 二者的結(jié)合(DBA)</p><p>  1.與C# 的連接:</p><p>  C# 提供了與底層數(shù)據(jù)庫系統(tǒng)緊密的連接。它支持不同的關(guān)系數(shù)據(jù)庫管理系統(tǒng)并充分發(fā)揮每一個(gè)數(shù)據(jù)庫的特長,生成獨(dú)立應(yīng)用或脫離服務(wù)器運(yùn)行的應(yīng)用程序。C# 連接數(shù)據(jù)庫的方式有兩種:</p><p>  方式一,通過使用C# 的 DATA控件;方式二,通過使用由C# 提供的專用的直

51、接與數(shù)據(jù)庫相連的接口。</p><p>  2.Mysql驅(qū)動(dòng)與DATA 控件的橋梁作用:</p><p>  使用Mysql公司的.NET驅(qū)動(dòng)包mysql-connector-net-6.0.3,并引用驅(qū)動(dòng)包內(nèi)已編譯好Mysql類組件,便可以更方便的在VisualStudio2008中操作Mysql數(shù)據(jù)庫。</p><p>  DATA在數(shù)據(jù)庫中的信息與將信息顯示

52、給用戶看的C# 程序之間架起了一座橋梁。我們可以設(shè)置DATA控件的各個(gè)屬性,告訴它要調(diào)用哪個(gè)數(shù)據(jù)庫的哪個(gè)部分。缺省情況下,DATA控件根據(jù)數(shù)據(jù)庫中的一個(gè)或多個(gè)數(shù)據(jù)表建立一個(gè)dynaset-type(動(dòng)態(tài)集合)類型的記錄集合。一個(gè)記錄集合是動(dòng)態(tài)的也就意味著,當(dāng)原來的數(shù)據(jù)表中的內(nèi)容改變了以后,該記錄集合中的記錄也會(huì)隨之改變。</p><p>  DATA控件還提供了用來瀏覽不同記錄的各種跳轉(zhuǎn)按鈕。將DATA控件放置在

53、窗體中之后,我們還必須在該控件與要處理的數(shù)據(jù)庫之間建立聯(lián)系。</p><p><b>  3.客戶端編程實(shí)現(xiàn)</b></p><p>  客戶端安裝在與服務(wù)器同一局域網(wǎng)的任意一臺(tái)計(jì)算機(jī)上,用戶通過正確用戶名與密碼便可登錄,并進(jìn)行與服務(wù)器或者其他客戶端的即時(shí)通信。</p><p>  下面將對(duì)客戶端的各功能進(jìn)行介紹:</p><

54、;p>  3.1 用戶登陸功能</p><p>  登陸界面如圖3-1所示:</p><p>  圖3-1 登陸界面圖</p><p>  賬號(hào)文本框:填寫用戶名;</p><p>  密碼文本框:填寫用戶密碼;</p><p>  服務(wù)器IP框:填寫服務(wù)器所在計(jì)算機(jī)的局域網(wǎng)IP地址;</p>&l

55、t;p>  服務(wù)器端口文本框:填寫服務(wù)器所開此服務(wù)的端口號(hào),本系統(tǒng)缺省默認(rèn)為服務(wù)器的“1234”端口。</p><p>  3.1.1 連接服務(wù)器</p><p>  使用類:System.Net.Sockets.TcpClent為TCP網(wǎng)絡(luò)服務(wù)提供客戶端連接,類: System.Net.Sockets.NetworkStream提供用于網(wǎng)絡(luò)訪問的基礎(chǔ)數(shù)據(jù)流。聲明為全局變量代碼如下:

56、</p><p>  TcpClient tcpClinet;//與服務(wù)器的連接(客戶端)</p><p>  private NetworkStream stream;//與服務(wù)器數(shù)據(jù)交互的流通道</p><p>  將用戶名、密碼、服務(wù)器IP、服務(wù)器端口號(hào)填寫完成后,點(diǎn)擊登陸按鈕,將實(shí)例化TcpClient類的新實(shí)例,并使用指定的IP地址與端口號(hào)將客戶端連接到T

57、CP主機(jī)。代碼如下:</p><p>  tcpClinet = new TcpClient();</p><p>  tcpClinet.Connect(IPAddress.Parse(txtServerIP.Text), Int32.Parse(txtDK.Text));//連接遠(yuǎn)程服務(wù)器</p><p>  其中txtServerIP.Text為服務(wù)器IP文本

58、框內(nèi)容 txtDK.Text為服務(wù)器端口號(hào)文本框內(nèi)容。</p><p>  然后返回用于發(fā)送和接收數(shù)據(jù)的NetworkStream:</p><p>  stream = tcpClinet.GetStream();</p><p>  3.1.2 開啟新線程用于接收服務(wù)器發(fā)回的消息</p><p>  在計(jì)算機(jī)的同一線程內(nèi)同時(shí)處理發(fā)出與接收

59、的消息是沒有保證的,所以編寫Incept()函數(shù)來接受服務(wù)器的請(qǐng)求。并開啟另外一個(gè)線程,用于接收服務(wù)器發(fā)回的消息,并作出相應(yīng)的處理。聲明新線程,并啟動(dòng),代碼如下:</p><p>  ThreadStart incept = new ThreadStart(this.Incept);</p><p>  Thread thread = new Thread(incept);</p&g

60、t;<p>  thread.Start();</p><p>  3.1.3 向服務(wù)器發(fā)送用戶名與密碼信息</p><p>  因?yàn)橛糜诰W(wǎng)絡(luò)訪問的基礎(chǔ)數(shù)據(jù)流的數(shù)據(jù)類型為字符編碼,所以將用戶名與密碼轉(zhuǎn)化為字符編碼數(shù)組,然后寫入基礎(chǔ)數(shù)據(jù)流NetworkStream,服務(wù)器便能接收到消息。</p><p>  創(chuàng)建字符串,以“CON”作為前綴,并以“|”符

61、號(hào)將用戶名與密碼隔開,以便服務(wù)器進(jìn)行分析,代碼如下:</p><p>  string userName = txtID.Text.ToString();</p><p>  string cmd = "CON|" + userName+ "|" + txtPASSWORD.Text + "|";</p><p

62、>  消息格式為:“CON|用戶名|密碼|”。</p><p>  然后將此字符串轉(zhuǎn)化為字符編碼數(shù)組,并寫入NetworkStream,代碼如下:</p><p>  Byte[] outbytes = System.Text.Encoding.Default.</p><p>  GetBytes(cmd.ToCharArray());</p>

63、<p>  stream.Write(outbytes, 0, outbytes.Length);//將指令發(fā)送給服務(wù)器</p><p>  若經(jīng)服務(wù)器驗(yàn)證無誤后,便會(huì)發(fā)回驗(yàn)證成功的指令,客戶端進(jìn)入系統(tǒng)。</p><p>  3.2 接收服務(wù)器發(fā)回的指令</p><p>  在新的線程內(nèi),啟動(dòng)接收函數(shù),接收服務(wù)器發(fā)回的不同信息,并判斷、處理。以便客戶端進(jìn)

64、行不同的操作。</p><p>  3.2.1 接收發(fā)回的原始消息并還原</p><p>  因?yàn)榉?wù)器發(fā)回的指令同樣為字符編碼數(shù)組,所以先聲明一個(gè)Byte類型的數(shù)組,用以接收服務(wù)器的原始信息:</p><p>  byte[] buff = new byte[10000000];</p><p>  int len;//消息長度</p

65、><p>  len = stream.Read(buff, 0, buff.Length);</p><p>  然后將收到的原始指令還原為字符串格式:</p><p>  String msg= System.Text.Encoding.Default.GetString(buff, 0, len);</p><p>  3.2.2 分析處理

66、服務(wù)器發(fā)回的指令</p><p>  因?yàn)榉?wù)器發(fā)回的消息與客戶端發(fā)出的消息類似,都是以指令名稱作為前綴,并以“|”符號(hào)作為分隔符,所以,聲明一個(gè)字符串型數(shù)組,并把消息內(nèi)以“|”符號(hào)隔開的各字符串放入此數(shù)組中:</p><p>  string[] token = msg.Split(new Char[] { '|' });</p><p>  在t

67、oken[0]內(nèi)放置的便為消息指令的標(biāo)示符。這樣,可以通過對(duì)token[0]內(nèi)字符串的判斷達(dá)到分析指令的目的。</p><p>  3.3 登陸后界面初始化</p><p>  3.3.1 驗(yàn)證成功與進(jìn)入主界面</p><p>  在密碼驗(yàn)證成功后,服務(wù)器將返回登陸成功消息,消息格式為:“EnterOK|”??蛻舳私邮沾讼ⅲ幚砗?,一個(gè)字符串?dāng)?shù)據(jù)類型的數(shù)組,<

68、;/p><p>  客戶端經(jīng)判斷后,如上消息,進(jìn)行相應(yīng)操作,代碼如下:</p><p>  If (token[0] == "EnterOK")</p><p><b>  {</b></p><p>  groupBox1.Dock = DockStyle.Fill;</p><p&

69、gt;  btnEnter.Enabled = false;</p><p><b>  }</b></p><p>  系統(tǒng)轉(zhuǎn)到用戶操作界面并將“確定”按鈕凍結(jié),防止多次向服務(wù)器發(fā)送連接指令,引發(fā)“此用戶已登錄”錯(cuò)誤。操作界面如圖3-2所示:</p><p>  圖3-2 系統(tǒng)主界面</p><p>  3.3.2 初

70、始化用戶列表</p><p>  進(jìn)入主界面后,首先會(huì)收到服務(wù)器發(fā)送的用戶列表,其原始消息的本身為一個(gè)DataSet,接收后將其還原:</p><p><b>  //創(chuàng)建內(nèi)存流</b></p><p>  MemoryStream memStream = new MemoryStream(buff);</p><p>

71、  memStream.Seek(0, SeekOrigin.Begin);//指定開始位置</p><p>  //產(chǎn)生二進(jìn)制序列化格式</p><p>  IFormatter formatter = new BinaryFormatter();</p><p>  //反串行化到內(nèi)存中</p><p>  object obj = fo

72、rmatter.Deserialize(memStream);</p><p><b>  //類型檢驗(yàn)</b></p><p>  if (obj is DataSet)</p><p><b>  {</b></p><p>  DataSet DS = (DataSet)obj;</p&

73、gt;<p><b>  }</b></p><p>  此時(shí),DataSet的新實(shí)例DS中的USERLIST表中。</p><p>  接下來將用戶列表展示在主界面上(將DS中USERLIST表內(nèi)數(shù)據(jù)展現(xiàn)在主界面上TreeView控件中)。因?yàn)榇瞬僮鳛榭缇€程操作,所以首先聲明一個(gè)委托,用于把DataSet中的內(nèi)容展現(xiàn)在TreeView控件上,并設(shè)置頭像

74、為不在線狀態(tài),委托于展現(xiàn)函數(shù)如下所示:</p><p>  private delegate void SetUsersListDel(DataSet dsList);//用于在TreeView中展示所有用戶</p><p>  private void SetUsersList(DataSet dsList)</p><p><b>  {</b&

75、gt;</p><p>  this.Invoke(new SetUsersListDel(SetAllUsersList),</p><p>  new object[]{dsList});</p><p><b>  }</b></p><p>  private void SetAllUsersList(DataS

76、et dsList)</p><p><b>  {</b></p><p>  foreach (TreeNode tn in treeView1.Nodes)</p><p><b>  {</b></p><p>  foreach (DataRow dr in dsList.Tables[&

77、quot;USERLIST"].Rows)</p><p><b>  {</b></p><p>  if (dr["classBM"].ToString() == tn.Tag.ToString())</p><p><b>  {</b></p><p>  Tr

78、eeNode tnChild = new TreeNode();</p><p>  tnChild.Text = dr["NAME"].ToString();</p><p>  tnChild.Tag = dr["ID"].ToString();</p><p>  tnChild.ImageIndex = 4;</

79、p><p>  tn.Nodes.Add(tnChild);</p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p&g

80、t;<p>  接收進(jìn)程中調(diào)用此委托的代碼如下:</p><p>  if (DS.Tables[0].TableName == "USERLIST")</p><p><b>  {</b></p><p>  SetUsersList(DS);//主進(jìn)程委托,用于在窗體TreeView中展現(xiàn)DS</p

81、><p><b>  }</b></p><p>  3.3.3 顯示在線用戶</p><p>  當(dāng)有新用戶上線時(shí),服務(wù)器便會(huì)將所有的在線用戶列表發(fā)送給包括此用戶在內(nèi)所有的在線用戶,客戶端接收此列表后,將在線用戶的頭像設(shè)置為在線狀態(tài),因?yàn)榇瞬僮魍瑯訛榭缇€程操作,所以使用委托,代碼如下:</p><p>  private

82、delegate void SetUsersListDelOnline(string[] token);//展示在線用戶</p><p>  private void SetUsersOnlineList(string[] token)</p><p><b>  {</b></p><p>  this.Invoke(new SetUsers

83、ListDelOnline(SetAllUserOnlineList), new object[] { token });</p><p><b>  }</b></p><p><b>  //在線用戶列表</b></p><p>  private void SetAllUserOnlineList(string[]

84、token)</p><p><b>  {</b></p><p>  for (int i = 1; i < token.Length - 1; i++)</p><p><b>  {</b></p><p>  string _onlineUser = token[i].ToStrin

85、g();</p><p>  foreach (TreeNode tn in treeView1.Nodes)</p><p><b>  {</b></p><p>  foreach (TreeNode _tn in tn.Nodes)</p><p><b>  {</b></p>

86、<p>  if (_tn.Text == _onlineUser)</p><p><b>  {</b></p><p>  _tn.ImageIndex = 3;//上線標(biāo)志</p><p><b>  }</b></p><p><b>  }</b>&l

87、t;/p><p><b>  }</b></p><p><b>  }</b></p><p><b>  }</b></p><p>  接收進(jìn)程中調(diào)用委托的代碼:</p><p>  else if (token[0] == "ULIST&q

88、uot;)</p><p><b>  {</b></p><p>  SetUsersOnlineList(token);//更新在線用戶列表</p><p><b>  }</b></p><p>  此時(shí),在主界面上的用戶列表內(nèi),便將所有用戶還在線用戶都顯示出來,如圖3-3所示:</p&

89、gt;<p><b>  圖3-3 用戶列表</b></p><p>  灰色頭像為不在線用戶,點(diǎn)亮的頭像為在線用戶。</p><p><b>  3.4 聊天功能</b></p><p>  此模塊的功能為,向指定用戶發(fā)送即時(shí)消息,通過服務(wù)器中轉(zhuǎn)、處理,最后接收用戶收到消息。并彈出對(duì)話框。</p>

90、;<p>  3.4.1 發(fā)送消息</p><p>  雙擊用戶節(jié)點(diǎn),彈出聊天窗口(以模式窗體方式彈出),并將對(duì)方用戶的用戶名傳入聊天窗口。代碼如下所示:</p><p>  private void treeView1_NodeMouseDoubleClick(object sender, </p><p>  TreeNodeMouseClickE

91、ventArgs e)</p><p><b>  {</b></p><p>  if (e.Node.Parent == null)</p><p><b>  {</b></p><p>  return;//若為根節(jié)點(diǎn)(班級(jí)節(jié)點(diǎn)),不做操作</p><p><b

92、>  }</b></p><p>  string ToUser = e.Node.Text;//對(duì)方用戶名</p><p>  string Msg = "";//內(nèi)容</p><p>  frmChatMain frm = new frmChatMain();</p><p>  frm.ToUser

93、 = ToUser;</p><p>  DialogResult dr=frm.ShowDialog(); </p><p><b>  }</b></p><p>  聊天窗口標(biāo)題為“與XXX聊天中”,XXX為好友用戶名,如圖3-4所示:</p><p>  圖3-4 發(fā)送消息框</p><p&g

94、t;  在聊天窗口(下側(cè)文本框)內(nèi)填寫發(fā)送內(nèi)容,點(diǎn)擊發(fā)送按鈕,聊天窗口(模式窗體)自動(dòng)關(guān)閉,并將所需參數(shù)返回,最后將消息以“CHAT|本機(jī)用戶名|對(duì)方用戶名|消息內(nèi)容”的格式發(fā)送給服務(wù)器,代碼如下:</p><p>  if (dr == DialogResult.OK)</p><p><b>  {</b></p><p>  Msg =

95、frm.Msg;</p><p>  string cmd = "CHAT|"+ userName + "|" + ToUser + "|" + Msg + "|";//格式為:CHAT|本用戶名|對(duì)方用戶名|內(nèi)容</p><p>  Byte[] outbytes = </p><p>

96、;  System.Text.Encoding.Default.GetBytes(cmd.ToCharArray());</p><p>  //將指令發(fā)送給服務(wù)器</p><p>  stream.Write(outbytes, 0, outbytes.Length);</p><p><b>  }</b></p><p

97、>  服務(wù)器接收此消息后,將內(nèi)容發(fā)送給接收方,便達(dá)到了即時(shí)通信的目的。</p><p>  3.4.2 接收消息</p><p>  當(dāng)其他用戶向本用戶發(fā)送即時(shí)消息時(shí),在本機(jī)用以接收服務(wù)器返回消息的副線程內(nèi),會(huì)收到一個(gè)編碼數(shù)組,通過客戶端處理后,指令標(biāo)示符放在了token數(shù)組的第一個(gè)單元內(nèi)。若此指令為“CHAT”,則彈出新窗口,顯示內(nèi)容。代碼如下:</p><p&

98、gt;  else if (token[0] == "CHAT")</p><p><b>  {</b></p><p>  string FromUser = token[1].ToString();</p><p>  string Msg = token[2].ToString();</p><p

99、>  frmChatMain frm = new frmChatMain();</p><p>  frm.ToUser = FromUser;</p><p>  frm.Msg = Msg;</p><p>  DialogResult dr = frm.ShowDialog();</p><p><b>  }</

100、b></p><p>  消息內(nèi)容顯示在消息框內(nèi),如圖3-5所示:</p><p>  圖3-5 接收消息框</p><p>  同樣可在下側(cè)回復(fù)框內(nèi)填寫回復(fù)消息,點(diǎn)擊“發(fā)送”按鈕,向?qū)Ψ桨l(fā)送回復(fù)消息,代碼如下所示:</p><p>  if (dr == DialogResult.OK)</p><p><

101、;b>  {</b></p><p>  Msg = frm.Msg;</p><p>  string cmd = "CHAT|" + userName + "|" + FromUser + "|" + </p><p>  Msg + "|";//格式為:CHAT|

102、本用戶名|對(duì)方用戶名|內(nèi)容</p><p>  Byte[] outbytes = </p><p>  System.Text.Encoding.Default.GetBytes(cmd.ToCharArray());</p><p>  //將指令發(fā)送給服務(wù)器</p><p>  stream.Write(outbytes, 0, out

103、bytes.Length);</p><p><b>  }</b></p><p>  若點(diǎn)擊關(guān)閉按鈕,客戶端不做任何操作。至此,聊天功能全部介紹完畢。</p><p>  3.5 查詢聊天記錄功能</p><p>  當(dāng)用戶不在線時(shí),便不能及時(shí)收到消息,只能在再次上線后通過查詢聊天記錄功能查詢離線消息。在服務(wù)器所在計(jì)

104、算機(jī)的數(shù)據(jù)庫中,存儲(chǔ)著所有用戶的所有在線離線消息,為日后的查詢提供了可能。</p><p>  鼠標(biāo)在用戶列表中單擊需要查詢歷史記錄的用戶名稱,然后單擊“聊天記錄”按鈕,客戶端創(chuàng)建字符串,以“QUERYLOGS”為前綴,并將此用戶用戶名,對(duì)方用戶名加入字符串,發(fā)送給服務(wù)器。字符格式為“QUERYLOGS|此機(jī)用戶名|對(duì)方用戶名|”。編寫代碼如下所示:</p><p>  private v

105、oid btnQuery_Click(object sender, EventArgs e)</p><p><b>  {</b></p><p>  if (userLogs == "")</p><p><b>  {</b></p><p>  MessageBox.Sh

106、ow("請(qǐng)先選擇好友,再進(jìn)行查詢", "提示");</p><p><b>  return;</b></p><p><b>  }</b></p><p>  //格式為:QUERY|本用戶名|對(duì)方用戶名</p><p>  string cmd = &q

107、uot;QUERYLOGS|" + userName + "|" + userLogs + "|";</p><p>  Byte[] outbytes = </p><p>  System.Text.Encoding.Default.GetBytes(cmd.ToCharArray());</p><p>  /

108、/將指令發(fā)送給服務(wù)器</p><p>  stream.Write(outbytes, 0, outbytes.Length);</p><p><b>  }</b></p><p>  將上述字符串發(fā)送給服務(wù)器后,經(jīng)過服務(wù)器處理,將會(huì)發(fā)回DataSet數(shù)據(jù),客戶端收到此消息指令后,將DataSet中名稱為“QUERYLOGS”的DataTa

109、ble的數(shù)據(jù)展示在彈出窗體的dataGridView中。</p><p>  在接收服務(wù)器指令的系統(tǒng)副進(jìn)程中,客戶端分析服務(wù)器發(fā)回的消息指令,處理后彈出新窗體的代碼如下所示:</p><p>  if (DS.Tables[0].TableName == "QUERYLOGS")</p><p><b>  {</b><

110、;/p><p>  frmQueryLogs frm = new frmQueryLogs();</p><p>  frm.FROMUSER = userName;</p><p>  frm.TOUSER = userLogs;</p><p>  frm.DATASET = DS;</p><p>  frm.Sho

111、wDialog();</p><p><b>  } </b></p><p>  編寫上述代碼中所彈出的新窗體,窗體中加入dataGridView控件,窗體標(biāo)題為“與XXX的聊天記錄”,“XXX”為對(duì)方用戶名。dataGridView控件內(nèi)顯示有發(fā)送方、接收方、發(fā)送時(shí)間、內(nèi)容四個(gè)字段。其中發(fā)送時(shí)間精確到毫秒。聊天記錄窗體顯示如圖3-6所示:</p>&

112、lt;p>  圖3-6 聊天記錄窗體</p><p>  上圖窗體內(nèi)在Form_Load事件內(nèi)編寫代碼設(shè)置窗體標(biāo)題,dataGridView控件的數(shù)據(jù)源、各列顯示名稱。代碼如下:</p><p>  private void frmQueryLogs_Load(object sender, EventArgs e)</p><p><b>  {&l

113、t;/b></p><p>  this.Text = "與好友:" + _toUser + "的聊天記錄";</p><p>  dataGridView1.DataSource = _ds.Tables[0];</p><p>  dataGridView1.Columns[0].HeaderText = "

114、;發(fā)送方:";</p><p>  dataGridView1.Columns[1].HeaderText = "接受方:";</p><p>  dataGridView1.Columns[2].HeaderText = "發(fā)送時(shí)間:";</p><p>  dataGridView1.Columns[3].Hea

115、derText = "內(nèi)容:";</p><p>  dataGridView1.Columns[3].Width = 300;</p><p><b>  }</b></p><p><b>  3.6 用戶離線</b></p><p>  當(dāng)用戶離線時(shí),服務(wù)器及時(shí)作出反應(yīng),將

116、此用戶狀態(tài)置為離線。并將離線消息發(fā)送給其他在線用戶,以便在線用戶更新在線用戶列表。</p><p>  3.6.1 發(fā)送離線請(qǐng)求</p><p>  當(dāng)用戶離線時(shí),點(diǎn)擊主操作界面的“退出”按鈕,客戶端創(chuàng)建離線請(qǐng)求字符串,并以“EXIT”作為前綴,并加入此用戶用戶名。字符串格式為“EXIT|用戶名|”,并將此請(qǐng)求發(fā)送給服務(wù)器,然后關(guān)閉主操作界面窗體,實(shí)現(xiàn)代碼如下:</p>&l

117、t;p>  private void btnExit_Click(object sender, EventArgs e)</p><p><b>  {</b></p><p>  string cmd = "EXIT|" + userName + "|";</p><p>  Byte[] out

118、bytes = System.Text.Encoding.Default.GetBytes(cmd.ToCharArray());</p><p>  stream.Write(outbytes, 0, outbytes.Length);//將指令發(fā)送給服務(wù)器</p><p>  this.Close();</p><p><b>  }</b>

119、;</p><p>  3.6.2 接收用戶離線消息</p><p>  當(dāng)其他用戶離線時(shí),服務(wù)器創(chuàng)建字符串,以“EXIT”作為前綴。在客戶端接收進(jìn)程內(nèi),將收到的指令處理后放入token字符串?dāng)?shù)組,數(shù)組的token[1]內(nèi)存放離線用戶用戶名,通過委托與編寫的SetUserOfflineList函數(shù),將離線用戶更新為離線狀態(tài),委托與SetUserOfflineList函數(shù)如下所示:</

120、p><p>  private delegate void SetUsersListDelOffline(string[] token);//離線用戶</p><p>  private void SetUserOffline(string[] token)</p><p><b>  {</b></p><p>  thi

溫馨提示

  • 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. 眾賞文庫僅提供信息存儲(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)論