版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、JISHOUUNIVERSITY專業(yè)課課程論文題 目:基于 TCP 協(xié)議的即時(shí)通信軟件的設(shè)計(jì)與實(shí)現(xiàn)作 者:學(xué) 號(hào):所屬學(xué)院:信息科學(xué)與工程學(xué)院專業(yè)年級(jí):總 評(píng) 分:完成時(shí)間:吉首大學(xué)信息科學(xué)與工程學(xué)院基于 TCP 協(xié)議的即時(shí)通信軟件的設(shè)計(jì)與實(shí)現(xiàn)(吉首大學(xué)信息科學(xué)與工程學(xué)院,湖南 吉首 )摘 要即時(shí)通信,由于其具有實(shí)時(shí)性、跨平臺(tái)性、成本低、效率高等優(yōu)點(diǎn)而受到廣泛的使用。設(shè)計(jì)并實(shí)現(xiàn)一個(gè)能夠處理多用戶進(jìn)行實(shí)時(shí)、安全的即時(shí)通信系統(tǒng)具有較強(qiáng)的現(xiàn)實(shí)意義。即時(shí)通信的底層通信是通過(guò)SOCKET 套接字接口實(shí)現(xiàn)的。當(dāng)前的主流UNIX 系統(tǒng)和微軟的WINDOWS 系統(tǒng)都在內(nèi)核提供了對(duì)SOCKET 字接口的支持。使
2、用這個(gè)統(tǒng)一的接口,可以編寫一個(gè)可移植的TCP/IP 通信程序。使信息能夠在INTERNET 上可靠的傳輸。本文設(shè)計(jì)并實(shí)現(xiàn)了基于局域網(wǎng)內(nèi)的簡(jiǎn)單即時(shí)通信系統(tǒng),系統(tǒng)采用C/S 模式,底層通信通過(guò)SOCKET 套接字接口實(shí)現(xiàn),服務(wù)器負(fù)責(zé)客戶端的登錄驗(yàn)證,好友信息的保存和心跳報(bào)文的發(fā)送。客戶端采用P2P 方式實(shí)現(xiàn)消息傳遞,并能實(shí)現(xiàn)文件的傳輸。本文首先討論了同步套接字,異步套接字,多線程并發(fā)執(zhí)行任務(wù)等;然后闡述了客戶端、服務(wù)器如何使用XML 序列化的消息進(jìn)行通信。關(guān)鍵詞:即時(shí)通信;文件傳輸;套接字;TCP 協(xié)議The Design and Implementation of Simple InstantM
3、essage Software Based on TCP Protocol AbstractYi Zhen kai(College of Information Science and Engineering,Jishou University,Jishou,Hunan )AbstractInstant messages have several advantages such as real-time, cross-platform, cheapand efficient. To design a Multi-user IM (instant message) architecture is
4、 very important in both theory and realism. Instant message based on TCP/IP protocol that is realized by socket interface. Almost all UNIX operation systems and Microsofts windows operation systems provide support of socket in the kernel. Using the uniform interface, we can develop a portable progra
5、m of TCP/IP, which help us transfer information in Internet safely and credibly.The system uses the client/server(C/S) mode. The server takes the responsibility of the login message of client, the saving of friend message and Message heartbeat. The transmission of the basic messages of the customer
6、end will be designed on P2P architecture. This thesis explains how the client and server communicate via serializing XML message.Key words: Instant Message; File Transfer; Socket; TCP protocol目 錄第一章 引 言11.1 課題背景11.2 國(guó)內(nèi)外研究現(xiàn)狀11.2.1國(guó)外研究現(xiàn)狀11.2.2 國(guó)內(nèi)研究現(xiàn)狀21.3課題研究的意義21.4 課題的研究方法2第二章 相關(guān)技術(shù)介紹32.1 TCP 協(xié)議32.1.1
7、TCP/IP 網(wǎng)絡(luò)協(xié)議32.1.2 TCP傳輸控制協(xié)議32.2套接字32.3流42.3.1 流的基本概念42.3.2 .NET 中的流42.4同步、異步、阻塞和非阻塞42.5C/S 模型52.6即時(shí)通信協(xié)議5第三章 系統(tǒng)總體設(shè)計(jì)73.1需求分析73.2系統(tǒng)基本架構(gòu)73.3功能模塊設(shè)計(jì)73.4邏輯圖93.5數(shù)據(jù)庫(kù)設(shè)計(jì)93.5.1實(shí)體關(guān)系圖9第四章 系統(tǒng)實(shí)現(xiàn)114.1使用 XML 定義的即時(shí)通信協(xié)議114.1.1信息結(jié)構(gòu)MESSAGE.CS&UMESSAGE.CS114.1.2數(shù)據(jù)結(jié)構(gòu)FriendStruct124.2數(shù)據(jù)庫(kù)連接類144.3服務(wù)器端154.3.1同步套接字網(wǎng)絡(luò)監(jiān)聽154.3.2多線
8、程174.3.3計(jì)時(shí)器174.4.1同步套接字客戶端184.4.2采用異步套接字的文件傳輸21結(jié) 論24參考文獻(xiàn)24第一章 引 言1.1 課題背景即時(shí)通信是一個(gè)終端連往一個(gè)即時(shí)通信網(wǎng)路的服務(wù)。即時(shí)通信不同于e-mail在于它的交談是實(shí)時(shí)的。大部分的即時(shí)通信服務(wù)提供了presence awareness 的特性顯示聯(lián)絡(luò)人名單,聯(lián)絡(luò)人是否在在線與能否與聯(lián)絡(luò)人交談。最早的即時(shí)通信軟件是ICQ,ICQ 是英文中I seek you 的諧音,意思是我找你。四名以色列青年于1996 年7 月成立Mirabilis 公司,并在11 月份發(fā)布了最初的ICQ版本,在六個(gè)月內(nèi)有85 萬(wàn)用戶注冊(cè)使用。在因特網(wǎng)上受歡
9、迎的即時(shí)通信服務(wù)包含了MSN Messenger、AOL Instant Messenger、Yahoo! Messenger、NET Messenger Service、Jabber、ICQ 與QQ。 這些服務(wù)有賴于許多想法更久的(與普遍)的在線聊天媒介,如Internet Relay Chat一樣知名。1970 年代早期,一種更早的即時(shí)通信形式是柏拉圖系統(tǒng)(PLATO system)。之后在1980 年代,UNIX/Linux 的交談實(shí)時(shí)信息被廣泛的使用于工程師與學(xué)術(shù)界,1990年代即時(shí)通信更跨越了因特網(wǎng)交流。1996 年11 月,ICQ 是首個(gè)廣泛被非UNIX/Linux使用者用于因特網(wǎng)
10、的即時(shí)通信軟件。在ICQ 的介紹之后,同時(shí)在許多地方有一定數(shù)量的即時(shí)通信方式發(fā)展,且各式的即時(shí)通信程序有獨(dú)立的協(xié)議,無(wú)法彼此互通。這引導(dǎo)使用者同時(shí)執(zhí)行兩個(gè)以上的即時(shí)通信軟件,或者他們可以使用支持多協(xié)議的終端軟件,如Gaim、Trillian 或Jabber。近年來(lái),許多即時(shí)通信服務(wù)開始提供視訊會(huì)議的功能,網(wǎng)絡(luò)電話(VoIP),與網(wǎng)絡(luò)會(huì)議服務(wù)開始整合為兼有影像會(huì)議與實(shí)時(shí)信息的功能。于是,這些媒體的分別變的越來(lái)越模糊。1.2 國(guó)內(nèi)外研究現(xiàn)狀1.2.1國(guó)外研究現(xiàn)狀當(dāng)今,國(guó)際上對(duì)網(wǎng)絡(luò)通信系統(tǒng)研究的較好的公司有,思科,Sun,Ms 等公司,思科主要研究的是底層的傳輸;MS,Sun 公司研究的是應(yīng)用層。其
11、中ms 公司憑借其在操作系統(tǒng)的壟斷地位,為了在網(wǎng)絡(luò)的發(fā)展中取得先機(jī),采用了各種各樣的手段。但是,其捆綁的msn,無(wú)論從功能上,還是技術(shù)上來(lái)說(shuō),都不算是非常先進(jìn)的。當(dāng)然,ie,同樣也不是很受人青睞,這讓人想起了,當(dāng)年的網(wǎng)景公司,網(wǎng)景只是生不逢時(shí)。MS 不擇手段的想打跨網(wǎng)景,可見(jiàn)其對(duì)網(wǎng)絡(luò)的重視。如今,Sun 公司在網(wǎng)絡(luò)應(yīng)用上捷足先登,憑借著Java,Sun 在網(wǎng)絡(luò)的應(yīng)用上領(lǐng)先于MS。微軟,想用同樣的辦法搞跨對(duì)手,因此它拿出了Visual c#,來(lái)對(duì)抗Java。這些都是在應(yīng)用層面的開發(fā)工具。應(yīng)用層上的產(chǎn)品就更顯種類繁多。ICQ 幾乎是國(guó)際上通用的即時(shí)通信工具,由于在我國(guó)它的應(yīng)用不是很廣,所以,其原理
12、也很少被介紹。msn,是MS 的產(chǎn)品,同樣在國(guó)內(nèi)沒(méi)什么市場(chǎng),所以,對(duì)其原理,也很少被討論過(guò)。至于ie,是在Visualc+下開發(fā)的產(chǎn)品,雖然有嚴(yán)重的安全隱患,不過(guò),至少能在某種程度上代表當(dāng)今國(guó)際研究的水平。此外,國(guó)際上最近出先了新的瀏覽器Firefox,其性能據(jù)說(shuō)是遠(yuǎn)高于ie,也許在網(wǎng)絡(luò)的天下,Ms 又有了更強(qiáng)勁的對(duì)手。1.2.2 國(guó)內(nèi)研究現(xiàn)狀國(guó)內(nèi)在應(yīng)用層上的網(wǎng)絡(luò)應(yīng)用軟件目前發(fā)展異常的火爆,因?yàn)槲覈?guó)有著網(wǎng)絡(luò)應(yīng)用的最大的市場(chǎng),現(xiàn)在國(guó)內(nèi)網(wǎng)絡(luò)的基礎(chǔ)性建設(shè)發(fā)展迅速,應(yīng)用軟件也層出不窮,其中,在游戲的領(lǐng)域中,網(wǎng)絡(luò)通信的工作做的不錯(cuò),如聯(lián)眾游戲平臺(tái),還有其他的一些平臺(tái),這些平臺(tái)基本上都是基于VC+的,用的
13、都是Socket 通信,但是為了效率,這些平臺(tái)沒(méi)有用MFC 提供的CSocket 類,而是直接用Socket 進(jìn)行通信。所以效率上不錯(cuò)。此外,tencent 的即時(shí)通信,也是做的很好的,從某中程度上來(lái)說(shuō),代表了國(guó)內(nèi)最高的水平。1.3課題研究的意義本課題目標(biāo)是實(shí)現(xiàn)局域網(wǎng)用戶之間的即時(shí)交流和文件傳輸,通過(guò)基礎(chǔ)的網(wǎng)絡(luò)SOKET 編程,為局域網(wǎng)內(nèi)部的即時(shí)通信提供一個(gè)簡(jiǎn)單而較安全的解決方案。1.4 課題的研究方法本系統(tǒng)采用 C/S(Client/Server)結(jié)構(gòu)進(jìn)行設(shè)計(jì),使用SQL Server 2000 構(gòu)建數(shù)據(jù)庫(kù),并在.NET 環(huán)境下使用Visual C#.net 語(yǔ)言和SOCKET 套接字開發(fā)一
14、個(gè)基于TCP 協(xié)議的簡(jiǎn)單即時(shí)通信軟件,實(shí)現(xiàn)簡(jiǎn)單的即時(shí)聊天,文件傳輸?shù)裙δ?。第二?相關(guān)技術(shù)介紹2.1 TCP 協(xié)議2.1.1 TCP/IP 網(wǎng)絡(luò)協(xié)議協(xié)議是對(duì)等的網(wǎng)絡(luò)實(shí)體之間通信的規(guī)則,可以簡(jiǎn)單地理解為網(wǎng)絡(luò)上各計(jì)算機(jī)彼此交流的一種“語(yǔ)言”。網(wǎng)絡(luò)通信協(xié)議設(shè)計(jì)的基本原則是層次化,層和協(xié)議的集合被稱為網(wǎng)絡(luò)體系結(jié)構(gòu)。相鄰層之間的接口定義了下層向上層提供的基本操作和服務(wù),下層向上層提供的服務(wù)分兩種形式:面向連接的服務(wù)和無(wú)連接的服務(wù)。 計(jì)算機(jī)網(wǎng)絡(luò)中已經(jīng)形成的網(wǎng)絡(luò)體系結(jié)構(gòu)主要有兩個(gè):OSI 參考模型和TCP/IP 參考模型。TCP/IP 參考模型是因特網(wǎng)(Internet)的基礎(chǔ)。和OSI 的7 層協(xié)議相比,
15、TCP/IP 協(xié)議只有4 個(gè)層次。通常說(shuō)的TCP/IP 是一組協(xié)議的總稱,TCP/IP 實(shí)際上是一個(gè)協(xié)議族,包括100 多個(gè)相互關(guān)聯(lián)的協(xié)議,其中IP(Internet Protocol, 網(wǎng)際協(xié)議)是網(wǎng)絡(luò)層最主要的協(xié)議;TCP(Transmission Control Protocol,傳輸控制協(xié)議)和UDP(User Datagram Protocol,用戶數(shù)據(jù)報(bào)協(xié)議是傳輸層中最主要的協(xié)議),一般認(rèn)為IP、TCP、UDP 是最根本的三種協(xié)議,是其他協(xié)議的基礎(chǔ)。2.1.2 TCP傳輸控制協(xié)議面向連接的通信可以使用可靠通信,在這時(shí)候,第四層協(xié)議發(fā)送數(shù)據(jù)接收方的確認(rèn),如果未收到數(shù)據(jù)或者數(shù)據(jù)被損壞,
16、則請(qǐng)求重新傳輸。TCP 協(xié)議就使用這種可靠通信。使用TCP 協(xié)議的應(yīng)用層協(xié)議包括HTTP、FTP、SMTP 和Telnet 等。TCP 要求在發(fā)送數(shù)據(jù)之前必須打開連接。服務(wù)器應(yīng)用程序必須執(zhí)行一個(gè)稱作被動(dòng)打開(passive open)的操作,以利用一個(gè)已知的端口號(hào)創(chuàng)建一個(gè)鏈接,這是,服務(wù)器并不是對(duì)網(wǎng)絡(luò)進(jìn)行呼叫,而是偵聽并等待引入的請(qǐng)求??蛻魬?yīng)用程序必須執(zhí)行一個(gè)主動(dòng)打開(active open),為此,它向服務(wù)器應(yīng)用程序發(fā)送一個(gè)同步序列號(hào)(SYN)以標(biāo)識(shí)連接。客戶應(yīng)用程序可以將動(dòng)態(tài)端口號(hào)作為本地端口使用。服務(wù)器必須向客戶發(fā)送一個(gè)確認(rèn)(ACK)以及服務(wù)器的序列號(hào)(SYN)。隨后,客戶回復(fù)一個(gè)ACK
17、,這樣就建立了鏈接?,F(xiàn)在可以發(fā)送和接收消息了。接收消息后,總是返回ACK 消息。如果在收到ACK之前發(fā)送方已經(jīng)超時(shí),則消息將被放到重發(fā)隊(duì)列中以再次發(fā)送。由于它的握手機(jī)制,所以TCP 協(xié)議比較復(fù)雜并且費(fèi)時(shí),但此協(xié)議在處理數(shù)據(jù)時(shí)對(duì)數(shù)據(jù)包的傳送有保障,從而使得在應(yīng)用程序協(xié)議中不需要再包括該功能。2.2套接字套接字這個(gè)術(shù)語(yǔ)并沒(méi)有定義某個(gè)協(xié)議:它具有兩層含義,但兩者都與一個(gè)協(xié)議相關(guān)。第一個(gè)含義是套接字編程API,它最初由伯克利大學(xué)為BSD UNIX 而創(chuàng)建。BSD套接字在經(jīng)過(guò)修改后被用作Windows 環(huán)境的編程接口(并且被命名為WinSock)。WinSock API 被包裝在System.Net.s
18、ockets 命名空間的.NET 類中。Windows Sockets是一個(gè)獨(dú)立于協(xié)議的編程接口,用于編寫網(wǎng)絡(luò)應(yīng)用程序。套接字的第二層含義表示一個(gè)用于在進(jìn)程間進(jìn)行通信的終端。在TCP/IP 中,每個(gè)終端都與一個(gè)IP 地址和一個(gè)端口號(hào)綁定。我們必須對(duì)流式套接字和數(shù)據(jù)報(bào)套接字這兩種類型進(jìn)行區(qū)分。流失套接字用TCP/IP 協(xié)議來(lái)使用面向連接的通信;另一方面,數(shù)據(jù)報(bào)套接字用UDP/IP 來(lái)使用無(wú)連接通信。2.3流2.3.1 流的基本概念流的概念已經(jīng)存在很長(zhǎng)時(shí)間了。流是一個(gè)用于傳輸數(shù)據(jù)的對(duì)象。數(shù)據(jù)的傳輸有兩個(gè)方向:1) 如果數(shù)據(jù)從外部源傳輸?shù)匠绦蛑校@就是讀取流。2) 如果數(shù)據(jù)從程序傳輸?shù)酵獠吭矗@就是
19、寫入流。外部源常常是一個(gè)文件,但也不完全都是文件,它還可以是:1) 網(wǎng)絡(luò),使用一定的網(wǎng)絡(luò)協(xié)議與網(wǎng)絡(luò)上其它計(jì)算機(jī)或終端交換數(shù)據(jù)。2) 一個(gè)指定的管道。3) 一塊內(nèi)存區(qū)域。 2.3.2 .NET 中的流在這些情況中,微軟提供了一個(gè).NET 基類System.IO.MemoryStream 來(lái)讀寫內(nèi)存數(shù)據(jù)使用System.Net.Sockets.NetworkStream 處理網(wǎng)絡(luò)數(shù)據(jù)。讀寫管道沒(méi)有相應(yīng)的流類,但有一個(gè)常見(jiàn)的流類System.IO.Stream,如果要編寫一個(gè)這樣的類,可以從這個(gè)基類繼承。流對(duì)外部數(shù)據(jù)源不做任何假定。外部源還可以是代碼中的一個(gè)變量,使用流在變量之間傳輸數(shù)據(jù)的技術(shù)是一個(gè)
20、非常有用的技巧,可以在數(shù)據(jù)類型之間轉(zhuǎn)換。在網(wǎng)絡(luò)編程中我們經(jīng)常會(huì)使用到網(wǎng)絡(luò)中的流對(duì):NetworkStream。它實(shí)現(xiàn)了.NET 中標(biāo)準(zhǔn)的Stream 機(jī)制,即可以使NetworkStream 通訊網(wǎng)絡(luò)套接字用標(biāo)準(zhǔn)的流操作進(jìn)行網(wǎng)絡(luò)數(shù)據(jù)的讀寫。它提供以下的功能:1) 一個(gè)統(tǒng)一的從網(wǎng)絡(luò)中讀取數(shù)據(jù)的方法;2) 與其他的.NET 流兼容,這樣你可以很容易地移植程序。2.4同步、異步、阻塞和非阻塞同步(synchronous):所謂同步方式,就是發(fā)送方發(fā)送數(shù)據(jù)包以后,不等接受方響應(yīng),就接著發(fā)送下一個(gè)數(shù)據(jù)包。異步(asynchronous):異步方式就是當(dāng)發(fā)送方發(fā)送一個(gè)數(shù)據(jù)包以后,一直等到接受方響應(yīng)后,才接
21、著發(fā)送下一個(gè)數(shù)據(jù)包。阻塞(Block):指執(zhí)行此套接字的網(wǎng)絡(luò)調(diào)用時(shí),直到調(diào)用成功才返回,否則此套節(jié)字就一直阻塞在網(wǎng)絡(luò)調(diào)用上,比如調(diào)用StreamReader 類的Readlin ( )方法讀取網(wǎng)絡(luò)緩沖區(qū)中的數(shù)據(jù),如果調(diào)用的時(shí)候沒(méi)有數(shù)據(jù)到達(dá),那么此Readlin ( )方法將一直掛在調(diào)用上,直到讀到一些數(shù)據(jù),此函數(shù)調(diào)用才返回。非阻塞(Unblock)指在執(zhí)行此套接字的網(wǎng)絡(luò)調(diào)用時(shí),不管是否執(zhí)行成功,都立即返回。同樣調(diào)用StreamReader 類的Readlin ( )方法讀取網(wǎng)絡(luò)緩沖區(qū)中數(shù)據(jù),不管是否讀到數(shù)據(jù)都立即返回,而不會(huì)一直掛在此函數(shù)調(diào)用上。在Windows 網(wǎng)絡(luò)通信軟件開發(fā)中,最為常用的
22、方法就是異步非阻塞套接字。平常所說(shuō)的C/S(客戶端/服務(wù)器)結(jié)構(gòu)的軟件采用的方式就是異步非阻塞模式的。 其實(shí)在用C進(jìn)行網(wǎng)絡(luò)編程中,我們并不需要了解什么同步、異步、阻塞和非阻塞的原理和工作機(jī)制,因?yàn)樵?Net FrameWrok SDK 中已經(jīng)已經(jīng)把這些機(jī)制給封裝好了。2.5C/S 模型客戶機(jī)/服務(wù)器模型,又稱為Client/Server 模型,簡(jiǎn)稱C/S 架構(gòu)。C/S 計(jì)算技術(shù)在信息產(chǎn)業(yè)當(dāng)中占有重要的地位。 這種客戶機(jī)/服務(wù)器模型是一種非對(duì)稱式編程模式。該模式的基本思想是把集中在一起的應(yīng)用劃分成為功能不同的兩個(gè)部分,分別在不同的計(jì)算機(jī)上運(yùn)行,通過(guò)它們之間的分工合作來(lái)實(shí)現(xiàn)一個(gè)完整的功能。對(duì)于這種
23、模式而言其中一部分需要作為服務(wù)器,用來(lái)響應(yīng)并為客戶提供固定的服務(wù);另一部分則作為客戶機(jī)程序用來(lái)向服務(wù)器提出請(qǐng)求或要求某種服務(wù)。在此“服務(wù)器”是指能在網(wǎng)絡(luò)上提供服務(wù)的任何程序。服務(wù)器接受網(wǎng)絡(luò)上的請(qǐng)求,完成服務(wù)后將結(jié)果返回給申請(qǐng)者。對(duì)于簡(jiǎn)單的服務(wù),把每個(gè)請(qǐng)求用一個(gè)IP 數(shù)據(jù)報(bào)發(fā)給服務(wù)器,服務(wù)器用另一個(gè)數(shù)據(jù)報(bào)返回響應(yīng)。客戶機(jī)和服務(wù)器都是獨(dú)立的計(jì)算機(jī)。當(dāng)一臺(tái)連入網(wǎng)絡(luò)的計(jì)算機(jī)向其他計(jì)算機(jī)提供各種網(wǎng)絡(luò)服務(wù)(如數(shù)據(jù)、文件的共享等)時(shí),它就被叫做服務(wù)器。而那些用于訪問(wèn)服務(wù)器資料的計(jì)算機(jī)則被叫做客戶機(jī)。嚴(yán)格說(shuō)來(lái),客戶機(jī)/服務(wù)器模型并不是從物理分布的角度來(lái)定義,它所體現(xiàn)的是一種網(wǎng)絡(luò)數(shù)據(jù)訪問(wèn)的實(shí)現(xiàn)方式。采用這種結(jié)構(gòu)
24、的系統(tǒng)目前應(yīng)用非常廣泛。如賓館、酒店的客房登記、結(jié)算系統(tǒng),超市的POS 系統(tǒng),銀行、郵電的網(wǎng)絡(luò)系統(tǒng)等。各種網(wǎng)絡(luò)服務(wù)器基本都遵循同樣的算法:創(chuàng)建一個(gè)端口(Port),接受從網(wǎng)絡(luò)上來(lái)的客戶服務(wù)請(qǐng)求,完成計(jì)算后把結(jié)果返回給客戶,如此反復(fù)。2.6即時(shí)通信協(xié)議協(xié)議是一系列的步驟,它包括雙方或者多方,設(shè)計(jì)它的目的是要完成一項(xiàng)任務(wù)。即時(shí)通信協(xié)議,參與的雙方或者多方是即時(shí)通信的實(shí)體。協(xié)議必須是雙方或者多方參與的,一方單獨(dú)完成的就不算協(xié)議。這樣在協(xié)議動(dòng)作的過(guò)程中,雙方必須交換信息,包括控制信息、狀態(tài)信息等等。這些信息的格式必須是協(xié)議參與方同意并且遵循的。好的協(xié)議要求清楚,完整,每一步都必須有明確的定義,并且不會(huì)
25、引起誤解;對(duì)每種可能的情況必須規(guī)定具體的動(dòng)作。有許多的 IM 系統(tǒng),如 AOL IM、Yahoo IM 和 MSN IM,它們使用了不同的技術(shù),而且它們互不兼容。為了創(chuàng)建即時(shí)通信的統(tǒng)一標(biāo)準(zhǔn),人們經(jīng)過(guò)了多次嘗試:IETF 的對(duì)話初始協(xié)議(SIP)和 即時(shí)通信對(duì)話初始協(xié)議和表示擴(kuò)展協(xié)議(SIMPLE)、應(yīng)用交換協(xié)議(APEX)、顯示和即時(shí)通信協(xié)議(PRIM)及基于 XML 且開放的可擴(kuò)展通信和表示協(xié)議(XMPP)協(xié)議(常稱為 Jabber 協(xié)議)。人們多次努力,試圖統(tǒng)一各大主要IM 供應(yīng)商的標(biāo)準(zhǔn)(AOL、Yahoo 及 Microsoft),但無(wú)一成功,且每一種 IM 仍然繼續(xù)使用自己所擁有的協(xié)議
26、。本系統(tǒng)目的在于實(shí)現(xiàn)一個(gè)簡(jiǎn)單的即時(shí)通信過(guò)程,沒(méi)有必要采用通用的比較復(fù)雜的即時(shí)通信協(xié)議,因此使用了簡(jiǎn)單定義的XML 標(biāo)記定義來(lái)規(guī)范即時(shí)通信的各種網(wǎng)絡(luò)信息,在網(wǎng)絡(luò)中傳輸序列化的XML 語(yǔ)言。第三章 系統(tǒng)總體設(shè)計(jì)3.1需求分析軟件針對(duì)局域網(wǎng)內(nèi)部用戶,實(shí)現(xiàn)用戶間的即時(shí)通信。需要分別實(shí)現(xiàn)服務(wù)器端和客戶端的軟件設(shè)計(jì)。服務(wù)器端負(fù)責(zé)監(jiān)聽用戶連接請(qǐng)求,負(fù)責(zé)連接數(shù)據(jù)庫(kù)存儲(chǔ)用戶信息,負(fù)責(zé)發(fā)送給用戶好友信息,負(fù)責(zé)發(fā)送心跳報(bào)文檢查用戶在線狀態(tài)并即時(shí)讓用戶更新好友在新信息??蛻舳税l(fā)起主動(dòng)連接,向服務(wù)器請(qǐng)求登錄或者注冊(cè)。客戶端可以修改昵稱,可以加已知用戶為好友(類似于MSN 的好友添加功能)??蛻舳酥g可以發(fā)起P2P 模式
27、的聊天,可以傳送文件。3.2系統(tǒng)基本架構(gòu)基于C/S 架構(gòu)的即時(shí)通信軟件便于對(duì)用戶信息進(jìn)行統(tǒng)一管理和保存,面向特定的用戶,對(duì)信息的安全控制能力很強(qiáng)。為了減輕服務(wù)器負(fù)擔(dān),客戶端之間的信息傳遞是采用P2P 模式的,服務(wù)器只負(fù)責(zé)用戶的注冊(cè),登錄和用戶在線狀態(tài)的檢驗(yàn)?;窘Y(jié)構(gòu)如圖:SERVER 注冊(cè)和登錄信息 注冊(cè)和登錄信息返回信息 返回信息CLIENTCLIENT聊天信息, 文件傳輸圖1 系統(tǒng)基本架構(gòu)3.3功能模塊設(shè)計(jì)CLIENT:1.注冊(cè):(1)可以完成客戶端注冊(cè),客戶端可以通過(guò)填寫信息進(jìn)行注冊(cè),信息被發(fā)送到服務(wù)器端。2.登錄:(1)客戶可以輸入賬號(hào)和密碼進(jìn)行登錄,客戶端會(huì)發(fā)送登錄信息等待服務(wù)器響應(yīng)
28、,登錄成功后會(huì)發(fā)出登錄成功信息并刷新好友列表。 3.修改:(1)密碼修改:應(yīng)該有密碼修改功能(2)信息修改:可以更改一些注冊(cè)信息4.通信:(1)即時(shí)聊天模塊:客戶端與客戶端之間建立線程進(jìn)行即時(shí)聊天,也包含有簡(jiǎn)單的對(duì)稱加解密算法功能。(2)好友列表:可以對(duì)好友列表進(jìn)行添加刪除等動(dòng)作。5.文件傳輸:(1)文件傳輸:文件傳輸功能SERVER:1.注冊(cè)回應(yīng):對(duì)客戶端傳送的注冊(cè)信息進(jìn)行判斷。(1)HASH 加密:對(duì)用戶的賬號(hào)和密碼信息進(jìn)行HASH 加密。(2)重復(fù)用戶檢查:將加密后信息與已存在賬號(hào)進(jìn)行比較,檢查是否賬號(hào)已存在,如果存在就返回錯(cuò)誤信息。(3)注冊(cè)成功:將可成功注冊(cè)的用戶賬號(hào)和密碼寫入數(shù)據(jù)庫(kù)
29、內(nèi),并向客戶端返回成功信息。2.修改回應(yīng):(1)對(duì)密碼和信息修改請(qǐng)求進(jìn)行判斷,執(zhí)行和返回修改成功信息3.登錄回應(yīng):(1)對(duì)登錄的賬號(hào)和密碼進(jìn)行加密檢查后發(fā)回正確或錯(cuò)誤情況,并記錄上線信息。(2)好友列表發(fā)送:給成功登錄的賬號(hào)發(fā)送好友列表及好友上線信息。(3)上線信息發(fā)送:給成功登錄的賬號(hào)的好友發(fā)送在線信息(包括IP,端口等等信息)。4.在線情況:(1)對(duì)登錄,在線,離線的用戶情況進(jìn)行統(tǒng)計(jì),記錄和通知。(2)心跳測(cè)試:每隔一段時(shí)間發(fā)送報(bào)文測(cè)試用戶是否因意外原因離線。(3)情況記錄:將用戶登錄時(shí)間,IP,下線時(shí)間等信息記錄入數(shù)據(jù)庫(kù)。 3.4邏輯圖圖 2 邏輯圖3.5數(shù)據(jù)庫(kù)設(shè)計(jì) 3.5.1實(shí)體關(guān)系圖
30、服務(wù)器是作為記錄和讀取數(shù)據(jù)庫(kù)信息的載體,與客戶端關(guān)系并不復(fù)雜,這里需要重點(diǎn)考慮客戶端之間的關(guān)系。用戶與用戶之間的關(guān)系是較為特殊的遞歸關(guān)系,即描述發(fā)生在兩個(gè)相同實(shí)體上的關(guān)系。E-R 圖如下:圖 3 E-R 圖第四章 系統(tǒng)實(shí)現(xiàn)4.1使用 XML 定義的即時(shí)通信協(xié)議4.1.1信息結(jié)構(gòu)MESSAGE.CS&UMESSAGE.CS這兩個(gè)C#類定義了包括服務(wù)器信息,狀態(tài)信息,注冊(cè)信息,登錄信息,聊天信息或者請(qǐng)求文件傳輸信息的函數(shù),服務(wù)器和客戶端通過(guò)將它們實(shí)例化和序列化再轉(zhuǎn)換成流在網(wǎng)絡(luò)上進(jìn)行傳輸。UMESSAGE.CS 主要代碼如下:Serializablepublic class UMessagepubl
31、ic UMessage() private string _nickname;private string _password;private string _accounts;private string _email;private int _info;/表示注冊(cè)或者登錄信息,客戶端信息0為注冊(cè),1為登錄;服務(wù)器返回信息0為用戶已存在,1為注冊(cè)成功,2為服務(wù)器未知錯(cuò)誤,3為CLIENT在線檢查,10為登錄失敗,11為登錄成功private Friend _friend;private int _fn;private string _fg;public string Nicknameget
32、return _nickname; set _nickname = value; public string Passwordget return _password; set _password = value; public string Accountsget return _accounts; set _accounts = value; public string Emailget return _email; set _email = value; public int Info get return _info; set _info = value; public Friend
33、Friget return _friend; set _friend = value; public int Fnget return _fn; set _fn = value; public string Fgget return _fg; set _fg = value; 由于MESSAGE.CS 與UMESSAGE.CS 類似,在此不再詳述。服務(wù)器和客戶端都可以通過(guò)相同的代碼對(duì)UMESSAGE 賦值, 再通過(guò)XmlSerializer 方法進(jìn)行將UMESSAGE 序列化為XML 文檔,最后將XML 文檔轉(zhuǎn)化為網(wǎng)絡(luò)流進(jìn)行傳輸。代碼如下:#region 將登錄信息轉(zhuǎn)為UMessagepriv
34、ate void Traslator()_message.Accounts=this.TextBox1.Text;_message.Nickname=;_message.Password=this.TextBox2.Text;_message.Email=;_message.Info=1;_message.Fri=null;#endregion4.1.2數(shù)據(jù)結(jié)構(gòu)FriendStruct服務(wù)器如果保存和傳遞用戶的好友信息是難點(diǎn)之一。數(shù)據(jù)庫(kù)的設(shè)計(jì)和信息的傳遞辨別都是比較難實(shí)現(xiàn)的。在數(shù)據(jù)庫(kù)方面,每個(gè)用戶擁有各自的好友分組信息(UserFav),分組中間使用“,”分隔,在TCP_FriendInfo
35、表中則分別保存了用戶ID 和好友ID,使用一個(gè)INT字段保存分組信息。數(shù)據(jù)庫(kù)以用戶ID 為標(biāo)準(zhǔn)對(duì)好友ID 和分組信息進(jìn)行內(nèi)連接查詢,就可以得到基本的好友信息了。代碼如下:select * from TCP_UserInfo join TCP_FriendInfo on TCP_FriendInfo.UserID= + uid+ and TCP_UserInfo.UserID=TCP_FriendInfo.FriendID在好友信息的傳輸方面,首先定義一個(gè)FriendStruct 數(shù)據(jù)結(jié)構(gòu)(當(dāng)然也可以用枚舉完成)如下:using System;using System.Collections.G
36、eneric;using System.Text;namespace TCPpublic class FriendStruct public struct FileInfopublic int filere;/接收和拒絕信息,1為接收,2為拒絕,3為取消public string filename;public long filelength;public struct Friend public string account;public string nickname;public string IP;public string status;public string fg;/好友分組在
37、MESSAGE.CS 或者UMESSAGE.CS 中,我們則定義了FriendStruct 的數(shù)組。在C#中使用DATAREADER 語(yǔ)句可以逐句讀取數(shù)據(jù)庫(kù)查詢的結(jié)果,再依次將結(jié)果賦值FriendStruct 數(shù)組元素,就得到了便于發(fā)送和讀取的存放好友信息的數(shù)組。賦值代碼如下:while (getf.Read() /getf即是以上的數(shù)據(jù)庫(kù)查詢的datareader語(yǔ)句ffi.account=getfUserAccount.ToString();ffi.IP = getfUserIP.ToString();ffi.nickname = getfUserNickname.ToString();f
38、fi.status = getfUserOnline.ToString();ffi.fg = getfFriendGroup.ToString();i+;getf.Close();4.2數(shù)據(jù)庫(kù)連接類實(shí)現(xiàn)一個(gè)快捷簡(jiǎn)單的數(shù)據(jù)庫(kù)連接的相關(guān)代碼是非常有必要的。實(shí)現(xiàn)的途徑也多種多樣,鑒于安全性和復(fù)雜性的需求不同,實(shí)現(xiàn)方法有簡(jiǎn)有繁。本設(shè)計(jì)使用了一個(gè)簡(jiǎn)單的類(UserData.CS)實(shí)現(xiàn)了簡(jiǎn)單快捷的數(shù)據(jù)庫(kù)連接和讀取。主要代碼如下:public static SqlConnection connStr = newSqlConnection(Server=D96B85DD938A465.;uid=sa;pwd=
39、change;database=TCPDB);Public static SqlDataReader SqlReader(string sql, SqlConnection connstr)SqlDataReader sqldr = null;SqlCommand cmd = new SqlCommand(sql, connstr);if (cmd.Connection.State.ToString() = Closed) cmd.Connection.Open();try sqldr = cmd.ExecuteReader();catch (Exception e)if (e != null
40、) sqldr = null;return sqldr;/數(shù)據(jù)庫(kù)操作連接public static string SqlCmd(string sql, SqlConnection connstr)string errorstr = null;SqlCommand sqlcmd = new SqlCommand(sql, connstr);if (sqlcmd.Connection.State.ToString() = Open)sqlcmd.Connection.Close();sqlcmd.Connection.Open();trysqlcmd.ExecuteNonQuery();catch
41、 (Exception e)if (e != null) errorstr = e.ToString();sqlcmd.Connection.Close();return errorstr;在UserData.CS 的基礎(chǔ)上,主程序可以更方便地實(shí)現(xiàn)數(shù)據(jù)庫(kù)連接操作,對(duì)數(shù)據(jù)庫(kù)進(jìn)行讀寫和更新。4.3服務(wù)器端服務(wù)器端的界面設(shè)計(jì)是基于便于測(cè)試的目的而實(shí)現(xiàn)的。如下圖:圖4 服務(wù)器端界面4.3.1同步套接字網(wǎng)絡(luò)監(jiān)聽基于同步套接字的網(wǎng)絡(luò)監(jiān)聽器對(duì)服務(wù)器來(lái)說(shuō)并不是最好的解決方案,但是仍然可行并且實(shí)現(xiàn)簡(jiǎn)單。主要代碼如下:開啟監(jiān)聽端口:public void Serve()int port = 8888;Server
42、IPEP = new IPEndPoint(IPAddress.Any, port);s = new Socket(ServerIPEP.AddressFamily, SocketType.Stream,ProtocolType.Tcp);s.Bind(EndPoint)ServerIPEP);s.Listen(10);alSock = new ArrayList();以下代碼讀取連入的連接,依次將連接加入可變長(zhǎng)數(shù)組alsock,并且讀取傳入的信息,進(jìn)行反串行化:while (true)tryuc = s.Accept();alSock.Add(uc);this.tb_states.Appen
43、dText(System.Convert.ToString(uc);byte data = new byte2048;int rect = uc.Receive(data);byte chat = new byterect;Buffer.BlockCopy(data, 0, chat, 0, rect);UMessage umessage = (UMessage)_translator.Deserialize(newMemoryStream(chat);int info = umessage.Info;對(duì)反串行化后的信息進(jìn)行處理,通過(guò)info 參數(shù)辨認(rèn)客戶端行為(注冊(cè)或者登錄),對(duì)注冊(cè)的信息進(jìn)
44、行數(shù)據(jù)庫(kù)查詢,注冊(cè)信息可插入,則將用戶信息插入數(shù)據(jù)庫(kù),否則返回客戶端“注冊(cè)出錯(cuò)”的信息:#region 處理用戶注冊(cè)信息if (info=0)/分辨出用戶發(fā)送的是注冊(cè)信息string Accounts = umessage.Accounts;SqlDataReader usdr = FPara.SqlReader(select * fromTCP_UserInfo where UserAccount= + Accounts + , FPara.connStr);if (usdr != null)if (usdr.Read()#region 此處寫入返回注冊(cè)失敗的代碼Socket sc = (S
45、ocket)alSockalSock.IndexOf(uc, 0);sc.Send(chat);#endregionelse#region 此處寫入插入數(shù)據(jù)庫(kù)用戶注冊(cè)信息的代碼Stream ms = new MemoryStream();Socket sc = (Socket)alSockalSock.IndexOf(uc, 0);if (FPara.SqlCmd(insert into TCP_UserInfo(UserAccount,UserNickname,UserEmail,JoinDate,UserIP,UserPassword) values( +umessage.Accounts
46、 + , + umessage.Nickname + , + umessage.Email + , +System.DateTime.Now.ToString() + , +(IPEndPoint)uc.RemoteEndPoint).Address.ToString() + , + umessage.Password + ),FPara.connStr) = null)umessage.Info = 1;_translator.Serialize(ms, umessage);byte d = new bytems.Length;ms.Seek(0, SeekOrigin.Begin);ms.
47、Read(d, 0, d.Length);sc.Send(d);elseumessage.Info = 2;_translator.Serialize(ms, umessage);byte d = new bytems.Length;ms.Seek(0, SeekOrigin.Begin);ms.Read(d, 0, d.Length);sc.Send(d);#endregionusdr.Close();#endregion4.3.2多線程對(duì)于服務(wù)器來(lái)說(shuō),多線程是必不可少的,否則它將無(wú)法處理不斷請(qǐng)求的新連接。C#的System.Threading 提供了多線程編程的支持。本設(shè)計(jì)實(shí)現(xiàn)代碼如下:t
48、his.th = new Thread(new ThreadStart(Serve);/新建一個(gè)用于監(jiān)聽的線程th.Start();/打開新線程不僅僅是服務(wù)器,基于P2P 模式聊天的客戶端也必須支持多線程運(yùn)行,實(shí)現(xiàn)代碼與之類似,在客戶端設(shè)計(jì)說(shuō)明中將不再敘述。4.3.3計(jì)時(shí)器計(jì)時(shí)器用于實(shí)現(xiàn)心跳報(bào)文的功能,服務(wù)器在啟動(dòng)以后就開始計(jì)時(shí),每隔定時(shí)間就向所有連入的客戶端發(fā)送信息,核心代碼如下:/用計(jì)時(shí)器檢查客戶端是否掉線System.Timers.Timer aTimer = new System.Timers.Timer();aTimer.Elapsed += new ElapsedEventHand
49、ler(CheckStatus);/ 設(shè)置引發(fā)時(shí)間的時(shí)間間隔 此處設(shè)置為5秒(毫秒)aTimer.Interval = 5000;aTimer.Enabled = true;CheckStatus 就是用于向客戶端發(fā)送檢查信息的方法,它會(huì)向遍歷連入的客戶端(alSock),然后依次向客戶端發(fā)送信息,如果發(fā)現(xiàn)客戶端沒(méi)有響應(yīng),就會(huì)如果發(fā)現(xiàn)對(duì)方無(wú)回應(yīng),則關(guān)閉相應(yīng)的SOCKET,并更新數(shù)據(jù)庫(kù)的用戶在線狀態(tài),同時(shí)向該用戶的所有好友發(fā)送用戶已下線的通知。 4.4客戶端 圖 5 注冊(cè)界面圖6 登錄、聊天、文件傳輸界面4.4.1同步套接字客戶端客戶端發(fā)起同步套接字連接,并傳送登錄或者注冊(cè)信息,由于兩者方式類似
50、,這里僅列出用戶登錄的代碼:#region 發(fā)送服務(wù)器登錄信息,并接收服務(wù)器反饋信息public void Client()建立SOCKET 發(fā)送信息:tryIPEndPoint ServerIPEP = newIPEndPoint(IPAddress.Parse(6),8888);c = newSocket(ServerIPEP.AddressFamily,SocketType.Stream,ProtocolType.Tcp);c.Connect(EndPoint)ServerIPEP);s = new MemoryStream();_translator.Seria
51、lize(s,_message);byte d=new bytes.Length;s.Seek(0, SeekOrigin.Begin);s.Read(d, 0, d.Length);int i = c.Send(d, 0, d.Length, SocketFlags.None);catch(Exception ex)MessageBox.Show(ex.Message);以下代碼讀取了服務(wù)器返回給客戶端的信息(注冊(cè)和登錄的成功與失?。?,如果返回了登錄成功的信息,還會(huì)讀取服務(wù)器給出的FriendStruct 結(jié)構(gòu)以得到用戶的好友信息:#region 接收反饋信息byte data = new
52、byte2048;while(true)int rect = c.Receive(data);byte chat = new byterect;Buffer.BlockCopy(data,0,chat,0,rect);UMessage bumessage = (UMessage)_translator.Deserialize(newMemoryStream(chat);string fg;string _fg=bumessage.Fg;if(bumessage.Info=3) else if(bumessage.Info=11)fg=_fg.Split(,); int xxx=bumessag
53、e.Fn;ff=bumessage.Fri;for(int i=0;ixxx;i+)string ems=new string5;ems0=ffi.account;ems1=ffi.nickname;ems2=fgint.Parse(ffi.fg);ems3=ffi.IP;ems4=ffi.status;ListViewItem item = new ListViewItem(ems); this.listView1.Items.Add(item);CSERVER 是一個(gè)用于開啟監(jiān)聽P2P 信息的方法,客戶端在登錄成功以后就會(huì)立刻開啟監(jiān)聽器,才能夠?qū)崿F(xiàn)與其它客戶端的聊天:th = new Thread(new ThreadStart(CServer);/新建一個(gè)用于監(jiān)聽其它客戶端信息的線程th.Start();/打開新線程MessageBox.Show(bumessage.Accounts+登錄成功!);this.Button1.Enabled=false;this.Button3.Enabled=false;else if (bumessage.Info=2)MessageBox.Show(服務(wù)器未知錯(cuò)誤);elseMessageBox.Show(bumessage.Info.ToString();#endregion#end
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(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ì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 2025年高職(建筑裝飾工程技術(shù))裝飾施工工藝綜合試題及答案
- 2025年中職機(jī)電基礎(chǔ)(機(jī)電認(rèn)知)試題及答案
- 2025年高職汽車修理(汽車底盤改裝)試題及答案
- 2025年中職寵物養(yǎng)護(hù)與馴導(dǎo)(寵物訓(xùn)練技巧)試題及答案
- 禁毒教育安全課件
- 禁毒與反洗錢培訓(xùn)課件
- 普華永道中國(guó)影響力報(bào)告2025
- 陜西省安康市漢陰縣2025-2026學(xué)年八年級(jí)上學(xué)期1月期末生物試題
- 2026廣西百色市平果市衛(wèi)生健康局公益性崗位人員招聘1人備考題庫(kù)及答案詳解(新)
- 高2023級(jí)高三上學(xué)期第5次學(xué)月考試地理試題
- 重慶市配套安裝工程施工質(zhì)量驗(yàn)收標(biāo)準(zhǔn)
- 2024新能源集控中心儲(chǔ)能電站接入技術(shù)方案
- 河南省信陽(yáng)市2023-2024學(xué)年高二上學(xué)期期末教學(xué)質(zhì)量檢測(cè)數(shù)學(xué)試題(含答案解析)
- 北師大版七年級(jí)上冊(cè)數(shù)學(xué) 期末復(fù)習(xí)講義
- 零售行業(yè)的店面管理培訓(xùn)資料
- 2023年初級(jí)經(jīng)濟(jì)師《初級(jí)人力資源專業(yè)知識(shí)與實(shí)務(wù)》歷年真題匯編(共270題)
- 培訓(xùn)課件電氣接地保護(hù)培訓(xùn)課件
- 污水管網(wǎng)工程監(jiān)理月報(bào)
- 安徽涵豐科技有限公司年產(chǎn)6000噸磷酸酯阻燃劑DOPO、4800噸磷酸酯阻燃劑DOPO衍生品、12000噸副產(chǎn)品鹽酸、38000噸聚合氯化鋁、20000噸固化劑項(xiàng)目環(huán)境影響報(bào)告書
- GB/T 17215.322-2008交流電測(cè)量設(shè)備特殊要求第22部分:靜止式有功電能表(0.2S級(jí)和0.5S級(jí))
- 英語(yǔ)音標(biāo)拼讀練習(xí)
評(píng)論
0/150
提交評(píng)論