版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、<p> 基于TCP/IP協(xié)議的網(wǎng)絡(luò)通信小應(yīng)用程序</p><p> 課程設(shè)計(jì)的題目及要求</p><p><b> 課程設(shè)計(jì)題目</b></p><p> 掌握基于TCP/IP協(xié)議實(shí)現(xiàn)網(wǎng)絡(luò)通信,理解TCP與UDP的不同特性以及實(shí)現(xiàn)方式。課程設(shè)計(jì)要求建立一個(gè)基于TCP/IP協(xié)議的網(wǎng)絡(luò)通信小應(yīng)用程序,實(shí)驗(yàn)可采用UDP或TCP,建
2、議基于WINDOWS平臺(tái)。</p><p><b> 功能要求</b></p><p> 建立一個(gè)基于中心服務(wù)器方式即時(shí)數(shù)據(jù)通信平臺(tái)(IM)。要求如下(*為選做內(nèi)容):</p><p> 1. 能進(jìn)行用戶(hù)管理,所有用戶(hù)必須登錄到服務(wù)器,由服務(wù)器維護(hù)在線信息。</p><p> 2. IM(Instant Mess
3、age)功能:用戶(hù)登錄后能進(jìn)行實(shí)時(shí)多方點(diǎn)到點(diǎn)短信息通信,如聊天;</p><p> 3. 能選擇要求服務(wù)器進(jìn)行轉(zhuǎn)發(fā)服務(wù);</p><p> 4. 能保存通信記錄到數(shù)據(jù)庫(kù)(SQL Server或其他桌面型數(shù)據(jù)庫(kù));</p><p> 5. 能進(jìn)行雙方文件傳輸,能顯示進(jìn)度;</p><p> 6. 支持?jǐn)帱c(diǎn)重傳。(檢查時(shí)需有功能隨時(shí)中斷傳
4、送,并在下次啟動(dòng)能顯示重傳狀態(tài));</p><p> *7. 數(shù)據(jù)包加密;</p><p> 8.實(shí)時(shí)語(yǔ)音雙向傳送功能;</p><p> *9.多方通話功能;</p><p> 10.界面設(shè)計(jì)要求布局合理,信息清晰。</p><p><b> 對(duì)于所有功能的要求</b></p&g
5、t;<p> 要求清晰描述所設(shè)計(jì)的應(yīng)答機(jī)制,數(shù)據(jù)包格式,所用數(shù)據(jù)結(jié)構(gòu)及其相應(yīng)算法,機(jī)密機(jī)制等;</p><p> 對(duì)于功能實(shí)現(xiàn)要求描繪實(shí)現(xiàn)方法,流程。</p><p> 開(kāi)發(fā)工具、軟硬件環(huán)境簡(jiǎn)介</p><p><b> 開(kāi)發(fā)工具</b></p><p> 開(kāi)發(fā)工具:Microsoft Visua
6、l Studio 2008</p><p><b> 軟硬件環(huán)境</b></p><p><b> 軟件環(huán)境</b></p><p> 操作系統(tǒng):Windows XP/Windows 7</p><p> 開(kāi)發(fā)軟件:Microsoft Visual Studio 2008</p>
7、<p><b> 開(kāi)發(fā)語(yǔ)言:C#語(yǔ)言</b></p><p> 平臺(tái):Microsoft.NET Framework v2.0</p><p><b> 硬件環(huán)境</b></p><p> 分辨率:1000×750</p><p> 服務(wù)器: PentiumIII
8、500以上或更高;</p><p> 內(nèi)存:128M以上;</p><p> 硬盤(pán):至少40G以上; </p><p> 工作站: PentiumII 266以上微機(jī);</p><p><b> 內(nèi)存:64MB</b></p><p> 硬盤(pán): 至少5G以上; </p>&
9、lt;p><b> 程序?qū)崿F(xiàn)的基本思想</b></p><p><b> 程序設(shè)計(jì)分析</b></p><p> 本設(shè)計(jì)實(shí)現(xiàn)的基于TCP/IP協(xié)議的網(wǎng)絡(luò)通信小應(yīng)用程序,實(shí)際上是一個(gè)基于Socket的聊天室。聊天室主要由聊天室服務(wù)器和聊天室客戶(hù)端組成。聊天室服務(wù)器負(fù)責(zé)管理和客戶(hù)端連接并發(fā)送消息給客戶(hù)端;聊天室客戶(hù)端負(fù)責(zé)接收或者發(fā)送聊天消
10、息,登錄聊天室服務(wù)器等。</p><p> 一個(gè)聊天室服務(wù)器應(yīng)該支持多個(gè)聊天室客戶(hù)端進(jìn)行同時(shí)連接。聊天室服務(wù)器和聊天室客戶(hù)端之間根據(jù)聊天協(xié)議進(jìn)行通信。</p><p><b> 基本思想</b></p><p> 程序的實(shí)現(xiàn)主要分為兩大部分,即服務(wù)器部分和客戶(hù)端部分。程序首先設(shè)計(jì)聊天室的服務(wù)器,再設(shè)計(jì)客戶(hù)端部分,最后生成可執(zhí)行文件。<
11、;/p><p><b> 服務(wù)器</b></p><p> 服務(wù)器端管理著聊天任務(wù),它維持著一張當(dāng)前在線用戶(hù)的列表,轉(zhuǎn)發(fā)用戶(hù)發(fā)送來(lái)的消息。設(shè)計(jì)思想如下:</p><p><b> 利用控件設(shè)計(jì)窗體;</b></p><p><b> 功能實(shí)現(xiàn);</b></p>
12、<p> 監(jiān)聽(tīng)本機(jī)IP地址中的一個(gè)指定的端口;</p><p> 當(dāng)有客戶(hù)端向該端口發(fā)出請(qǐng)求時(shí),服務(wù)器程序立刻建立一個(gè)與該客戶(hù)端的連接并啟動(dòng)一個(gè)新的線程來(lái)處理該客戶(hù)端;</p><p> 根據(jù)客戶(hù)端發(fā)送來(lái)的各種不同的請(qǐng)求,執(zhí)行相應(yīng)的操作,并將結(jié)果返回給客戶(hù)端。</p><p><b> 運(yùn)行調(diào)試。</b></p>
13、<p><b> 客戶(hù)端</b></p><p> 客戶(hù)端應(yīng)用程序包含用戶(hù)登錄窗口和用戶(hù)聊天的主窗口,它允許用戶(hù)登錄到服務(wù)器,可以向服務(wù)器發(fā)送消息,同時(shí)可以接收從服務(wù)器返回的信息。</p><p> 設(shè)計(jì)登錄窗體和聊天窗體;</p><p> 基于課程設(shè)計(jì)的要求實(shí)現(xiàn)各窗體對(duì)應(yīng)的功能;</p><p>
14、; 向服務(wù)器發(fā)送連接請(qǐng)求;</p><p> 得到服務(wù)器程序的確認(rèn)后,建立與服務(wù)器的連接,并獲得與服務(wù)器交互的流通道;</p><p> 通過(guò)網(wǎng)絡(luò)流通道與服務(wù)器端的程序進(jìn)行數(shù)據(jù)通信。</p><p><b> 運(yùn)行調(diào)試。</b></p><p> 系統(tǒng)功能框架圖、系統(tǒng)流程圖</p><p&g
15、t;<b> 功能框架圖</b></p><p><b> 圖1 功能框架圖</b></p><p><b> 系統(tǒng)流程圖</b></p><p><b> 圖2系統(tǒng)流程圖</b></p><p><b> 具體實(shí)現(xiàn)過(guò)程</b&
16、gt;</p><p><b> 設(shè)計(jì)準(zhǔn)備</b></p><p><b> TCP的運(yùn)用</b></p><p> 客戶(hù)端只能和服務(wù)器通信,無(wú)法和另外一個(gè)客戶(hù)端直接通信。為了使兩個(gè)客戶(hù)端能相互通信,所有的客戶(hù)一律先把聊天信息發(fā)給服務(wù)器,并告訴服務(wù)器改信息是發(fā)送給哪個(gè)客戶(hù)的,服務(wù)器收到信息后,再將該信息轉(zhuǎn)發(fā)給另外一個(gè)
17、客戶(hù)。本設(shè)計(jì)的實(shí)現(xiàn)主要用了TcpListener類(lèi)用于用于偵聽(tīng)和接受傳入的連接請(qǐng)求。</p><p><b> 基本方法:</b></p><p> 表1 TCP連接基本方法</p><p> Socket套接字的運(yùn)用</p><p> 本設(shè)計(jì)中自定義了通信程序的可識(shí)別命令(見(jiàn)以下第三小點(diǎn)),即自定義的簡(jiǎn)單協(xié)議
18、。故程序中為支持自定義的協(xié)議,采用套接字來(lái)實(shí)現(xiàn)。</p><p> 根據(jù)連接啟動(dòng)的方式以及本地套接字要連接的目標(biāo),套接字之間的連接過(guò)程可以分為服務(wù)器監(jiān)聽(tīng),客戶(hù)端請(qǐng)求,連接確認(rèn)三個(gè)步驟。</p><p> 服務(wù)器監(jiān)聽(tīng):服務(wù)器套接字并不定位具體的客戶(hù)端套接字,而是處于等待連接的狀態(tài),實(shí)時(shí)監(jiān)控網(wǎng)絡(luò)狀態(tài)。</p><p> 客戶(hù)端請(qǐng)求:由客戶(hù)端的套接字提出連接請(qǐng)求,要
19、連接的目標(biāo)是服務(wù)器的套接字。為此,客戶(hù)端的套接字必須首先描述它要連接的服務(wù)器的套接字,指出服務(wù)器套接字的地址和端口號(hào),然后再向服務(wù)器套接字提出連接請(qǐng)求。</p><p> 連接確認(rèn):當(dāng)服務(wù)器套接字監(jiān)聽(tīng)到客戶(hù)端套接字的連接請(qǐng)求時(shí),它就響應(yīng)客戶(hù)端套接字的請(qǐng)求,把服務(wù)器套接字的信息發(fā)給客戶(hù)端,一旦客戶(hù)端確認(rèn)了此信息,連接即可建立。而服務(wù)器套接字繼續(xù)監(jiān)聽(tīng)其他客戶(hù)端套接字的連接請(qǐng)求。</p><p&g
20、t; 服務(wù)器和客戶(hù)端必須分別進(jìn)行編程,它們之間的連接如下圖所示。</p><p> 圖3 服務(wù)器與客戶(hù)端的連接圖</p><p> 通信程序中可識(shí)別命令的定義</p><p> 程序中定義的可識(shí)別命令格式為兩個(gè)一位整數(shù)拼接成的字符串,每位的含義如下:</p><p> 第一位 第一位為0:客戶(hù)機(jī)向服務(wù)器發(fā)送的命令</p
21、><p> 第一位為1:服務(wù)器向客戶(hù)機(jī)發(fā)送的命令</p><p><b> "01"-離線</b></p><p> "02"-請(qǐng)求在線列表</p><p> 可以識(shí)別的命令格式 "03"-請(qǐng)求對(duì)所有人閃屏振動(dòng)</p><p>
22、 服務(wù)端 "04"-請(qǐng)求對(duì)指定用戶(hù)閃屏振動(dòng) "05"-請(qǐng)求廣播消息</p><p> "06"-請(qǐng)求對(duì)指定用戶(hù)發(fā)送文件</p><p> 要求轉(zhuǎn)發(fā)給指定用戶(hù)的用戶(hù)名 :轉(zhuǎn)發(fā)給指定用戶(hù)</p>
23、;<p> "11"-服務(wù)器要求客戶(hù)機(jī)更新在線列表</p><p> 客戶(hù)端 "12"-服務(wù)器要求客戶(hù)機(jī)做閃屏振動(dòng)</p><p> default-接受用戶(hù)消息或者系統(tǒng)消息的正文</p><p><b> 服務(wù)器具體設(shè)計(jì)</b></p><p><
24、;b> 窗體設(shè)計(jì)</b></p><p> 新建一個(gè)Windows窗體,命名為Form1.cs,主要用于連接服務(wù)器。只有建立了聊天室服務(wù)器,客戶(hù)才能連接到上面,從而進(jìn)行聊天。服務(wù)器建立之后,一般處于監(jiān)聽(tīng)狀態(tài),等待客戶(hù)機(jī)的連接申請(qǐng)。</p><p> 窗體用到的主要控件如下表所示。</p><p><b> 表2 主要控件<
25、/b></p><p><b> 圖4 窗體設(shè)計(jì)圖</b></p><p><b> 編碼</b></p><p><b> 創(chuàng)建服務(wù)器</b></p><p> 這部分程序的編寫(xiě)主要是實(shí)現(xiàn)“獲得有效的端口號(hào)和IP地址”,設(shè)計(jì)要點(diǎn):</p><
26、;p><b> 自動(dòng)獲取IP地址</b></p><p> IPAddress _ip = new System.Net.IPAddress(Dns.GetHostByName(Dns.GetHostName()).AddressList[0].Address);</p><p> 可以自主選擇是否輸入端口號(hào)</p><p> 端
27、口號(hào)是進(jìn)程的標(biāo)識(shí),端口號(hào)范圍從0到65535。由于1000以?xún)?nèi)的端口大多被標(biāo)準(zhǔn)協(xié)議占用,所以程序中可以自由使用的端口號(hào)一般都用大于1000的值。</p><p> 若輸入端口號(hào),程序設(shè)置了有效端口號(hào)的范圍為1023與65535之間。若端口有效則連接服務(wù)器,并提示相應(yīng)的信息;</p><p> 默認(rèn)端口號(hào)設(shè)置為8888</p><p> 若沒(méi)有輸入端口號(hào),或者端
28、口號(hào)無(wú)效,則程序自動(dòng)使用默認(rèn)端口號(hào)連接服務(wù)器。</p><p><b> 代碼如下:</b></p><p> private void button1_Click(object sender, EventArgs e)</p><p> { this.button1.Enabled = false;</p><p&
29、gt; string portParam;</p><p> portParam = textBox_port.Text;</p><p> if (portParam != string.Empty)</p><p> { if (!int.TryParse(portParam, out _port) || _port < 1023 || _po
30、rt > 65535)</p><p><b> {</b></p><p> _port = 8888;</p><p> textBox1 .AppendText ("端口號(hào)不合法,默認(rèn)端口號(hào)被接受!");</p><p><b> } }</b></p
31、><p> textBox1 .AppendText ("服務(wù)器已啟動(dòng),正在監(jiān)聽(tīng)...\n");</p><p> textBox1 .AppendText (string.Format("服務(wù)器IP:{0}\t端口號(hào):{1}\n", _ip, _port));</p><p> _tcpl =new TcpListener
32、 (_ip, _port);</p><p> _tcpl.Start();</p><p> trd = new Thread(new ThreadStart(this.ThreadTask));</p><p> trd.Start(); </p><p><b> }</b></p>&l
33、t;p><b> 線程監(jiān)聽(tīng)和執(zhí)行</b></p><p> 由服務(wù)器和客戶(hù)端的聊天室模型可以看出,服務(wù)器跟客戶(hù)端的連接以及客戶(hù)端之間的連接都是通過(guò)執(zhí)行流實(shí)現(xiàn)的,即每一個(gè)獨(dú)立的執(zhí)行流都是一個(gè)線程。編寫(xiě)線程監(jiān)聽(tīng)和線程執(zhí)行體監(jiān)聽(tīng)來(lái)自多個(gè)客戶(hù)端的請(qǐng)求。</p><p><b> 線程監(jiān)聽(tīng)</b></p><p> 在
34、創(chuàng)建服務(wù)器代碼中,可以看到若輸入端口號(hào)有效,則執(zhí)行TcpListener類(lèi)偵聽(tīng)和接受傳入的連接請(qǐng)求,并開(kāi)啟線程調(diào)用ThreadTask方法。</p><p> ThreadTask方法要點(diǎn):</p><p> Socket套接字接受連接方法;</p><p> 驗(yàn)證用戶(hù)名是否唯一,若當(dāng)前哈希表沒(méi)有該用戶(hù)允許連接,否則連接失??;</p><p
35、><b> 調(diào)用線程執(zhí)行體;</b></p><p> 向所有用戶(hù)發(fā)送系統(tǒng)消息,AppendText方法在文本框中追加入系統(tǒng)消息,并用foreach循環(huán)將系統(tǒng)消息傳給各個(gè)客戶(hù)端。</p><p><b> 線程執(zhí)行體</b></p><p> 線程執(zhí)行體主要用于客戶(hù)端和服務(wù)器轉(zhuǎn)發(fā)消息。線程執(zhí)行體實(shí)際上也是聊天
36、室中服務(wù)器端的聊天依據(jù),即我們自定義的協(xié)議解析。這部分的程序流程如下圖。</p><p> 圖5 客戶(hù)端程序流程圖</p><p><b> 退出連接</b></p><p> 編程要點(diǎn):(1)TCP停止監(jiān)聽(tīng);</p><p> (2)清除在線列表。</p><p><b>
37、 代碼如下:</b></p><p> private void button2_Click(object sender, EventArgs e)</p><p> {if (_tcpl != null)</p><p><b> {</b></p><p> _tcpl.Stop();}</
38、p><p> //關(guān)閉客戶(hù)端連接并清理資源</p><p> if (_transmit_tb.Count != 0)</p><p> { foreach (Socket session in _transmit_tb.Values)</p><p><b> {</b></p><p>
39、 session.Shutdown(SocketShutdown.Both);</p><p><b> }</b></p><p> _transmit_tb.Clear();</p><p> _transmit_tb = null;</p><p><b> } </b><
40、/p><p><b> Close();}</b></p><p><b> 客戶(hù)端具體設(shè)計(jì)</b></p><p><b> 登錄窗體</b></p><p><b> 窗體設(shè)計(jì)圖</b></p><p> 新建一個(gè)Wind
41、ows窗體,命名為login_frm.cs,主要用于驗(yàn)證登錄信息,保證登錄的用戶(hù)不重復(fù),端口號(hào)和IP地址有效。</p><p> 主要控件如下表所示:</p><p> 表3 用戶(hù)端登錄界面的窗體設(shè)計(jì)</p><p> 圖6 用戶(hù)登陸界面</p><p><b> 程序要點(diǎn)</b></p>&l
42、t;p><b> TCP連接</b></p><p> 新建一個(gè)TCP連接類(lèi)TCPConnection,初始化IP地址、端口號(hào)和TcpClient新實(shí)例,使用指定的IP地址和端口號(hào)連接到TCP主機(jī)。</p><p><b> 驗(yàn)證登錄信息</b></p><p> 用戶(hù)輸入用戶(hù)名、服務(wù)器IP地址和端口號(hào),若是
43、輸入的IP地址無(wú)效,則提示“IP地址不合法”;如果輸入的端口號(hào)無(wú)法轉(zhuǎn)化為等效的32位有符號(hào)整數(shù),或不在1024-65535之間,則提示“端口號(hào)不合法”。否則則進(jìn)行服務(wù)器連接。</p><p> 向服務(wù)器發(fā)出連接請(qǐng)求并向服務(wù)器發(fā)送用戶(hù)名以確認(rèn)身份</p><p> 如果客戶(hù)端連接不到服務(wù)器,則提示“無(wú)法連接到服務(wù)器,請(qǐng)重試”,不然向服務(wù)器發(fā)送用戶(hù)名以確認(rèn)身份,將輸入的用戶(hù)名轉(zhuǎn)化為UTF-
44、16格式的編碼,寫(xiě)入NetworkStream,再進(jìn)行讀取,若是已經(jīng)存在,則提示"您的用戶(hù)名已經(jīng)被使用,請(qǐng)嘗試其他用戶(hù)名!",如果不存在,則獲取當(dāng)前登錄窗體的文本,并進(jìn)入聊天界面。</p><p><b> 聊天窗體</b></p><p><b> 窗體設(shè)計(jì)</b></p><p> 新建一個(gè)W
45、indows窗體,作為一個(gè)聊天的界面。 選擇聊天室則進(jìn)行廣播,選擇悄悄話則進(jìn)行一對(duì)一聊天,點(diǎn)對(duì)點(diǎn)地發(fā)送文件。還可修改皮膚顏色,對(duì)發(fā)送數(shù)據(jù)進(jìn)行加密、解密。</p><p> 窗體用到的主要控件如表所示。</p><p> 表4 客戶(hù)端主界面的聊天窗口設(shè)計(jì)</p><p><b> 線程執(zhí)行體</b></p><p>
46、; 這部分是與服務(wù)器相對(duì)應(yīng)的。當(dāng)客戶(hù)端連接到服務(wù)器后,服務(wù)器立刻建立一個(gè)數(shù)據(jù)接收的獨(dú)立線程。在接收線程中,對(duì)命令進(jìn)行解析處理。程序流程如下圖。</p><p> 圖 7 客戶(hù)端程序框圖</p><p><b> 功能模塊</b></p><p><b> 聊天功能</b></p><p>
47、<b> 一對(duì)多聊天</b></p><p> 在聊天室模式下進(jìn)行聊天信息發(fā)送,則將相關(guān)信息寫(xiě)入網(wǎng)絡(luò)流,并向服務(wù)器發(fā)送廣播請(qǐng)求。本地信息接收框會(huì)顯示聊天狀態(tài)、發(fā)送時(shí)間和信息內(nèi)容,其它所有在線用戶(hù)會(huì)顯示發(fā)送方用戶(hù)名、發(fā)送時(shí)間和信息內(nèi)容。</p><p><b> 相關(guān)代碼:</b></p><p> //如果是聊天室
48、模式則向服務(wù)器發(fā)送廣播請(qǐng)求</p><p> if (broadcast_rb.Checked)</p><p><b> {</b></p><p> localTxt = string.Format("[廣播]您在 {0} 對(duì)所有人說(shuō):\r\n{1}\r\n\r\n", DateTime.Now, msg);<
49、;/p><p> sendTxt = string.Format("[廣播]{0} 在 {1} 對(duì)所有人說(shuō):\r\n{2}\r\n\r\n", _username, DateTime.Now, msg);</p><p><b> //發(fā)送廣播請(qǐng)求</b></p><p> _nws.Write(new byte[] {
50、0, 5 }, 0, 2); //_nws是用于發(fā)送和接收信息的網(wǎng)絡(luò)流</p><p><b> }</b></p><p><b> 一對(duì)一私聊</b></p><p> 選擇進(jìn)行“悄悄話”,則需要在當(dāng)前在線用戶(hù)在選擇一方進(jìn)行聊天,沒(méi)有選擇用戶(hù)則無(wú)法進(jìn)行通信,會(huì)有提示“請(qǐng)選擇一個(gè)接收者!\n如果沒(méi)有接受者可選,表明
51、當(dāng)前只有您一個(gè)人在線”。</p><p> 發(fā)送方會(huì)接收到消息,提示發(fā)送時(shí)間、接收者的用戶(hù)名和發(fā)送的內(nèi)容,接收方會(huì)接收到發(fā)送方的用戶(hù)名、發(fā)送時(shí)間和發(fā)送的內(nèi)容。</p><p><b> 聊天記錄</b></p><p><b> 保存聊天記錄</b></p><p> 點(diǎn)擊保存聊天記錄,會(huì)創(chuàng)
52、建一個(gè)SaveFileDialog新實(shí)例,另存文件類(lèi)型設(shè)定為*.txt,輸入保存的文件名,就會(huì)將當(dāng)前接收信息文本框的所有內(nèi)容以文本文件保存。</p><p> private void save_btn_Click(object sender, EventArgs e)</p><p><b> {</b></p><p> Dialog
53、Result ret;</p><p> SaveFileDialog sfd = new SaveFileDialog();</p><p> sfd.Filter = "文本文件(*.txt)|*.txt";</p><p> sfd.AddExtension = true;</p><p> if ((ret
54、 = sfd.ShowDialog()) == DialogResult.OK)</p><p><b> {</b></p><p> chatrcd_rtb.SaveFile(sfd.FileName, RichTextBoxStreamType.PlainText);</p><p><b> }</b><
55、;/p><p><b> }</b></p><p><b> 清除聊天記錄</b></p><p> 點(diǎn)擊清除聊天記錄的按鈕后,出現(xiàn)提示信息“確實(shí)消除嗎?消除后不可恢復(fù)。”選擇確定則調(diào)用clear()方法將當(dāng)前的接收信息框的內(nèi)容全部清空。</p><p> 圖8 清除聊天記錄提示窗口<
56、/p><p><b> 文件傳輸</b></p><p><b> 選擇文件</b></p><p> 點(diǎn)擊“選擇文件”,進(jìn)入打開(kāi)文件對(duì)話框,根據(jù)文件類(lèi)型篩選文件,找到要發(fā)送的文件,點(diǎn)擊確定后,讀取所選文件所在路徑名。</p><p><b> 發(fā)送文件</b></p
57、><p> 這一功能只能在“悄悄話”中實(shí)現(xiàn),在“聊天室”模式下會(huì)提示“不能在聊天室發(fā)送文件”,還需要選擇一個(gè)接收方,否則會(huì)提示“請(qǐng)選擇一個(gè)接收者!\n如果沒(méi)有接受者可選,表明當(dāng)前只有您一個(gè)人在線”。如果文件路徑名為空,則提示“請(qǐng)選擇文件傳輸路徑”,否則,根據(jù)路徑名為指定的路徑名初始化StreamReader的一個(gè)新實(shí)例sr,讀取文件內(nèi)容,關(guān)閉sr,并釋放與讀取器相關(guān)的所有系統(tǒng)資源,并啟動(dòng)控制發(fā)送進(jìn)度條的定時(shí)器。&l
58、t;/p><p><b> 保存文件</b></p><p> 點(diǎn)擊接收文件,彈出保存文件對(duì)話框,選擇文件保存路徑;為指定路徑的指定文件初始化StreamWriter新實(shí)例,使用TextWriter.WriteLine(String value)方法將后跟行結(jié)束符的字符串寫(xiě)入文本流,同時(shí)啟動(dòng)控制進(jìn)度條的定時(shí)器。</p><p><b>
59、; 數(shù)據(jù)加密</b></p><p> 這部分采用RSA算法來(lái)實(shí)現(xiàn)。先初始化RSA對(duì)象,再使用RSA算法進(jìn)行解密和加密。下表是RSA算法應(yīng)用方法的說(shuō)明。</p><p> 表5 算法應(yīng)用方法的說(shuō)明</p><p><b> 具體代碼實(shí)現(xiàn)如下:</b></p><p> /// <summar
60、y></p><p> /// 使用RSA算法進(jìn)行解密</p><p> /// </summary></p><p> /// <param name="text">要加密的字符串</param></p><p> /// <returns></retu
61、rns></p><p> private string RSAEncrypt(string text)</p><p><b> {</b></p><p> RSACryptoServiceProvider rsa = GetRSAProviderFromContainer("rsa1");</p>
62、;<p> byte[] bytes = Encoding.Unicode.GetBytes(text);</p><p> byte[] encryptedData = rsa.Encrypt(bytes, true);</p><p> return Convert.ToBase64String(encryptedData);</p><p>
63、;<b> }</b></p><p> /// <summary></p><p> /// 使用RSA算法進(jìn)行解密</p><p> /// </summary></p><p> /// <param name="text">要解密的字符串</
64、param></p><p> /// <returns></returns></p><p> private string RSADescrpt(string text)</p><p><b> {</b></p><p> RSACryptoServiceProvider r
65、sa = GetRSAProviderFromContainer("rsa1");</p><p> byte[] encryptedData = Convert.FromBase64String(text);</p><p> byte[] decryptedData = rsa.Decrypt(encryptedData, true);</p>&
66、lt;p> return Encoding.Unicode.GetString(decryptedData);</p><p><b> }</b></p><p> /// <summary></p><p> /// 獲取初始化RSA對(duì)象</p><p> /// </summary
67、></p><p> /// <param name="containerName">密鑰容器名</param></p><p> /// <returns>RSA對(duì)象</returns></p><p> private static RSACryptoServiceProvider
68、GetRSAProviderFromContainer(string containerName)</p><p><b> {</b></p><p> CspParameters cp = new CspParameters();</p><p> //將 ProviderType初始化為值24,該值指定PROV_RSA_AES提供程
69、序</p><p> cp.ProviderType = 24;</p><p> //如果不存在名為containerName的密鑰容器,則創(chuàng)建之,并初始化cp</p><p> //如果存在,則直接根據(jù)它保存的內(nèi)容初始化cp</p><p> cp.KeyContainerName = containerName;</p&g
70、t;<p> RSACryptoServiceProvider rsa = new RSACryptoServiceProvider(cp);</p><p> return rsa;</p><p><b> }</b></p><p><b> 運(yùn)行結(jié)果及分析</b></p><
71、;p><b> 服務(wù)器</b></p><p> 創(chuàng)建連接后,服務(wù)器一直處于監(jiān)聽(tīng)狀態(tài),同時(shí)用AppendText方法不斷追加文本,顯示系統(tǒng)消息在文本框中。示意圖如下。</p><p><b> 圖9 服務(wù)器界面</b></p><p><b> 客戶(hù)端</b></p>&
72、lt;p><b> 登錄窗體</b></p><p> 登錄窗體的設(shè)計(jì)只涉及驗(yàn)證用戶(hù)名是否唯一、端口號(hào)是否有效、服務(wù)器IP是否合法。并沒(méi)有提供新用戶(hù)的注冊(cè),這是本設(shè)計(jì)的不足之一。如果端口號(hào)不正確,用戶(hù)名不唯一,程序都提供相應(yīng)的提示。</p><p> 圖10 服務(wù)器登陸錯(cuò)誤提示</p><p><b> 聊天窗體<
73、;/b></p><p><b> 聊天主窗體</b></p><p> 圖11 聊天主窗體</p><p><b> 保存聊天記錄</b></p><p> 點(diǎn)擊聊天窗體的“保存聊天記錄”按鈕,彈出對(duì)話框如下圖,命名文件名字,按“保存”就可得到存儲(chǔ)聊天記錄的txt文本。</p
74、><p> 圖12 保存聊天記錄窗口</p><p><b> txt內(nèi)容顯示圖:</b></p><p><b> 圖13 消息記錄</b></p><p><b> 文件傳輸</b></p><p> 文件傳輸進(jìn)度效果圖:</p>
75、;<p> 圖14 文件傳輸進(jìn)度效果圖</p><p><b> 數(shù)據(jù)加密</b></p><p> 圖15 數(shù)據(jù)加密效果圖</p><p><b> 接收方內(nèi)容顯示圖:</b></p><p> 圖16 接收方內(nèi)容顯示圖</p><p><
76、;b> 總結(jié)</b></p><p><b> 王曉珊總結(jié)</b></p><p> 這次課程設(shè)計(jì)雖然總體感覺(jué)很難,但在這個(gè)過(guò)程中學(xué)到了很多新的知識(shí)。本次課程設(shè)計(jì)建立一個(gè)基于TCP/IP協(xié)議的網(wǎng)絡(luò)通信小應(yīng)用程序,它的功能類(lèi)似于我們生活中經(jīng)常使用的QQ,我想每個(gè)做了這個(gè)課程設(shè)計(jì)的同學(xué),至少都學(xué)到了一點(diǎn),那就是知道我們所用的QQ軟件是用什么怎么開(kāi)發(fā)
77、出來(lái)的。以下是我做課程設(shè)計(jì)的幾點(diǎn)總結(jié)。</p><p> 程序設(shè)計(jì)知識(shí)方面,這次的設(shè)計(jì)涉及了TCP,Socket套接字,線程,網(wǎng)絡(luò)流等網(wǎng)絡(luò)應(yīng)用編程知識(shí)??梢哉f(shuō)對(duì)于這些知識(shí)我都很陌生。開(kāi)始設(shè)計(jì)時(shí),通過(guò)書(shū)籍查閱,并利用視頻學(xué)習(xí)才弄清了整個(gè)設(shè)計(jì)的思路。這才使整個(gè)設(shè)計(jì)找到了起點(diǎn)。通信應(yīng)用程序兩個(gè)客戶(hù)之間的通信必須通過(guò)客戶(hù)端來(lái)實(shí)現(xiàn),因此分別設(shè)計(jì)服務(wù)器和客戶(hù)端是必要的。對(duì)于服務(wù)端,啟動(dòng)服務(wù)器后TcpListener監(jiān)聽(tīng)端口
78、,當(dāng)有客戶(hù)端連接后,通過(guò)AcceptSocket返回與客戶(hù)端連接的Socket對(duì)象,然后通過(guò)讀寫(xiě)Socket對(duì)象完成與聊天室客戶(hù)端的數(shù)據(jù)傳輸。而客戶(hù)端啟動(dòng)后,則創(chuàng)建Socket對(duì)象并通過(guò)對(duì)象連接服務(wù)器,成功后通過(guò)socket完成數(shù)據(jù)的接收和發(fā)送。此外,服務(wù)器和客戶(hù)端的每個(gè)連接都是線程的使用。</p><p> 程序設(shè)計(jì)遇到的問(wèn)題方面,一方面是線程Thread類(lèi)的使用,經(jīng)常出現(xiàn)各種錯(cuò)誤。比如,運(yùn)行客戶(hù)端程序后,用
79、可執(zhí)行文件打開(kāi)另外一個(gè)窗口進(jìn)行通信,程序就會(huì)出現(xiàn)如下圖的錯(cuò)誤,并顯示“線程間操作無(wú)效”,但是如果兩個(gè)窗口同時(shí)是用可執(zhí)行文件打開(kāi),則不會(huì)出現(xiàn)這樣的錯(cuò)誤。另一方面是數(shù)據(jù)加密與解密的設(shè)計(jì),主要使用了RSA算法。所遇到的問(wèn)題是解密的設(shè)計(jì)一直沒(méi)法運(yùn)行成功。出現(xiàn)錯(cuò)誤的現(xiàn)象是運(yùn)行的兩個(gè)聊天窗體同時(shí)消失。最后我們并沒(méi)有將解密算法成功的應(yīng)用,而采用了簡(jiǎn)單的同時(shí)發(fā)送加密碼和文本消息,并在接收方顯示。</p><p> 程序改進(jìn)方面
80、,一是我們的登錄部分沒(méi)有設(shè)置新用戶(hù)的注冊(cè),只要用戶(hù)名唯一,端口與IP正確即可成功登錄。這會(huì)給用戶(hù)登錄造成混亂。另一方面,設(shè)計(jì)的解密功能沒(méi)有真正實(shí)現(xiàn)。最后,語(yǔ)音功能與斷點(diǎn)傳送功能都是程序可以擴(kuò)充改進(jìn)的地方。</p><p> 綜合本次設(shè)計(jì),我們小組嚴(yán)格按照設(shè)計(jì)的要求,分析應(yīng)用程序開(kāi)發(fā)的要點(diǎn),通過(guò)資料與視頻學(xué)習(xí),從窗體設(shè)計(jì)到功能實(shí)現(xiàn),最后設(shè)計(jì)實(shí)現(xiàn)了網(wǎng)絡(luò)通信等功能。</p><p><b
81、> 黃如萍總結(jié)</b></p><p> 這次計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì),加深了我網(wǎng)路協(xié)議和套接字編程的了解,雖然有限,但是通過(guò)實(shí)驗(yàn)學(xué)習(xí)基本上能夠把協(xié)議設(shè)計(jì)思想應(yīng)用到現(xiàn)實(shí)應(yīng)用中,實(shí)現(xiàn)一些通信功能。</p><p> 這次課程設(shè)計(jì)我們是采用C#語(yǔ)言來(lái)編程的,雖然曾經(jīng)使用過(guò),對(duì)一些控件的使用和某些方法有一定的了解,但是由于不熟悉網(wǎng)絡(luò)應(yīng)用編程,設(shè)計(jì)過(guò)程中還是遇到不少的困難,編程過(guò)
82、程中對(duì)一些錯(cuò)誤總是找不出原因,或者需要花費(fèi)更多的時(shí)間來(lái)修改。剛開(kāi)始時(shí)對(duì)使用的一些方法的應(yīng)用上也有些問(wèn)題,不熟悉的情況下很可能想用其它的方法來(lái)實(shí)現(xiàn),導(dǎo)致功能上欠缺或者產(chǎn)生一些沖突。</p><p> 這是第一次編寫(xiě)基于服務(wù)端和客戶(hù)端的網(wǎng)絡(luò)程序,剛開(kāi)始時(shí)總是挺疑惑:怎樣才能實(shí)現(xiàn)邏輯連接?覺(jué)得自己很難辦到。但事實(shí)是,事在人為。沒(méi)有嘗試永遠(yuǎn)都不知道事情的可能性到底有多大,實(shí)踐總是檢驗(yàn)問(wèn)題最直接有效的方法。這次課程設(shè)計(jì)加
83、深我對(duì)網(wǎng)絡(luò)協(xié)議的理解的同時(shí),也擴(kuò)展了知識(shí)面。因而在今后的學(xué)習(xí)工作中,我還會(huì)多動(dòng)手練習(xí),更好的加深理解和鞏固知識(shí)結(jié)構(gòu)。</p><p> 由于能力有限,所以有些功能還是沒(méi)能實(shí)現(xiàn),例如語(yǔ)音通話和斷點(diǎn)重傳,很想加入,但老是失敗,雖然有些遺憾,但是我們?cè)诔绦蛑屑尤肫渌δ?,包括閃屏振動(dòng)和界面皮膚選擇,使得界面更加生動(dòng)和靈活,也算是種“補(bǔ)償”吧。本來(lái)是嘗試建一個(gè)數(shù)據(jù)庫(kù)來(lái)實(shí)現(xiàn)用戶(hù)管理和信息存放的,但是編程過(guò)程中總是得顧慮到
84、數(shù)據(jù)庫(kù)應(yīng)該如何實(shí)現(xiàn),因?yàn)闀r(shí)間的關(guān)系也只能擱淺。</p><p> 這次課程設(shè)計(jì)還有一個(gè)很大的缺點(diǎn):對(duì)異常情況的考慮不足,對(duì)異常的處理不夠。導(dǎo)致連接上一出問(wèn)題就意外終止或者沒(méi)法再操作,得重新啟動(dòng)。</p><p><b> 參考文獻(xiàn)</b></p><p> [1]謝希仁.計(jì)算機(jī)網(wǎng)絡(luò)(第五版).北京:電子工業(yè)出版社.2007.5.</
85、p><p> [2]馬俊. C#網(wǎng)絡(luò)應(yīng)用編程(第二版).北京:人民郵電出版社.2010.1</p><p> [3]譚桂華,魏亮. Visual C#高級(jí)編程范例.北京:清華大學(xué)出版社.2004.4</p><p> [4]吳晨,陳建孝. C# 網(wǎng)絡(luò)與通信程序設(shè)計(jì)案例精講. 北京:清華大學(xué)出版社.2006.10</p><p> [5]劉
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 眾賞文庫(kù)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 軟件設(shè)計(jì)tcpip網(wǎng)絡(luò)通信程序設(shè)計(jì)實(shí)驗(yàn)報(bào)告
- 網(wǎng)絡(luò)通信課程設(shè)計(jì)
- 網(wǎng)絡(luò)通信winsock課程設(shè)計(jì)
- 計(jì)算機(jī)網(wǎng)絡(luò)課程設(shè)計(jì)--基于tcpip協(xié)議的網(wǎng)絡(luò)監(jiān)聽(tīng)程序設(shè)計(jì)
- 網(wǎng)絡(luò)通信課程設(shè)計(jì)--公寓網(wǎng)絡(luò)設(shè)計(jì)
- 網(wǎng)絡(luò)通信winsock課程設(shè)計(jì)--ip地址管理程序
- 南京郵電大學(xué)軟件設(shè)計(jì)tcpip網(wǎng)絡(luò)通信程序設(shè)計(jì)實(shí)驗(yàn)報(bào)告
- 基于gui的網(wǎng)絡(luò)通信程序設(shè)計(jì)
- tcpip網(wǎng)絡(luò)聊天課程設(shè)計(jì)
- vb課程設(shè)計(jì)--打字練習(xí)應(yīng)用程序
- java課程設(shè)計(jì)報(bào)告--java桌面應(yīng)用程序設(shè)計(jì)開(kāi)發(fā)
- java課程設(shè)計(jì)報(bào)告---計(jì)算器應(yīng)用程序?qū)嶒?yàn)報(bào)告
- java課程設(shè)計(jì)報(bào)告--“即時(shí)通”網(wǎng)絡(luò)通信系統(tǒng)的設(shè)計(jì)與開(kāi)發(fā)
- 內(nèi)部通訊系統(tǒng)-應(yīng)用程序開(kāi)發(fā)課程設(shè)計(jì)
- 網(wǎng)絡(luò)工程課程設(shè)計(jì)---基于cs的簡(jiǎn)單通信通信協(xié)議
- 網(wǎng)絡(luò)綜合課程設(shè)計(jì)---windows平臺(tái)下tcpip協(xié)議的設(shè)計(jì)與實(shí)現(xiàn)
- 課程設(shè)計(jì)--實(shí)現(xiàn)計(jì)算器功能的應(yīng)用程序
- 基于tcp的網(wǎng)絡(luò)通信協(xié)議設(shè)計(jì)畢業(yè)設(shè)計(jì)論文
- 基于tcp的網(wǎng)絡(luò)通信協(xié)議設(shè)計(jì)畢業(yè)設(shè)計(jì)論文
- java課程設(shè)計(jì)-- 實(shí)現(xiàn)計(jì)算器功能的應(yīng)用程序
評(píng)論
0/150
提交評(píng)論