樂在其中

          以JEE為主攻,以Flex為點(diǎn)綴,以Eclipse RCP為樂趣
          請?jiān)L問http://www.inframesh.org

          首頁 新隨筆 聯(lián)系 管理
            43 Posts :: 0 Stories :: 8 Comments :: 0 Trackbacks

          本文重點(diǎn)在于對飛鴿協(xié)議原理及部分網(wǎng)絡(luò)知識進(jìn)行普及性的介紹,盡量避免用專業(yè)的術(shù)語嚇跑非計(jì)算機(jī)專業(yè)朋友,如果有介紹的不合理的地方,也歡迎高手出來拍磚。
          飛鴿概述
          飛鵒傳書作為免費(fèi)的開源軟件,在全世界各國享有聲譽(yù),其原作者是H.Shirouzu,其windows平臺的C++源碼下載地址為http://www.azhi.net/IPMsg/ipmsg206src.zip。除windows平臺的實(shí)現(xiàn)以外,還存在大量其它平臺的飛鴿實(shí)現(xiàn),如Mac,Linux,甚至還存在平臺無關(guān)的Java版本。
          本人開發(fā)的飛鴿傳書,實(shí)際上是在M8平臺上實(shí)現(xiàn)了該協(xié)議子集。從而能夠?qū)崿F(xiàn)局域網(wǎng)內(nèi)用戶發(fā)現(xiàn),接收PC版飛鴿傳入的消息、文件、文件夾。
          本人實(shí)現(xiàn)的飛鴿,可參考如下兩個(gè)帖子:
          1 http://bbs.meizu.com/thread-791903-1-1.html
          2 http://bbs.meizu.com/thread-814371-1-1.html
          飛鴿能夠?qū)崿F(xiàn)這種異構(gòu)平臺之間的通信,在于它的源碼和協(xié)議是開放的,只要遵守相應(yīng)的傳輸協(xié)議,就可以實(shí)現(xiàn)通信。
          這里要強(qiáng)調(diào)一個(gè)概念,網(wǎng)絡(luò)傳輸類應(yīng)用程序,協(xié)議是重中之重。那么,協(xié)議到底是什么呢?協(xié)議可以讓運(yùn)行于兩個(gè)不同平臺的程序之間做到“心有靈犀一點(diǎn)通”,也有點(diǎn)像黑幫內(nèi)部的切口:A說了天王蓋地虎,B就要說寶塔鎮(zhèn)荷妖。
          有點(diǎn)扯遠(yuǎn)了,計(jì)算機(jī)網(wǎng)絡(luò)應(yīng)用中的協(xié)議,是要解決一些很實(shí)際的問題,比如,以飛鴿為例,計(jì)算機(jī)A向計(jì)算機(jī)B可以發(fā)消息,也可以傳文件。都是通過網(wǎng)絡(luò)傳遞數(shù)據(jù),B如何能知道,這些數(shù)據(jù)中什么是消息,什么是文件呢?這就需要設(shè)計(jì)通信協(xié)議,通過一些命令字描述當(dāng)前或即將傳送的數(shù)據(jù)是什么內(nèi)容。從而使得接收方,能夠正確理解發(fā)送方發(fā)出的內(nèi)容。
          網(wǎng)絡(luò)基礎(chǔ),TCP/IP協(xié)議簡介
          TCP/IP是很復(fù)雜的,要介紹這個(gè)已經(jīng)遠(yuǎn)遠(yuǎn)超出我的能力范圍,但我仍然可以對它的上層使用做簡單的介紹。
          前面我們花了大量的篇幅加口水強(qiáng)調(diào)協(xié)議在網(wǎng)絡(luò)應(yīng)用中的重要性。那所謂的飛鴿協(xié)議,與我們平時(shí)常常聽到的TCP/IP有什么區(qū)別和聯(lián)系呢?這個(gè)問題問的好(我自己問的)!
          計(jì)算機(jī)網(wǎng)絡(luò)的設(shè)計(jì)有著非常多的成功的可取之處,其中之一就是分層。按照問題所在的領(lǐng)域,將問層劃分到不同的層中去解決(讀者可自行參考OSI的七層模型以及TCP/IP的五層模型)。TCP/IP協(xié)議在傳輸層提供的UDP和TCP傳輸協(xié)議,成為了我們構(gòu)建應(yīng)用層軟件(如,聊天,下載,郵件,http等等)的基礎(chǔ)。
          TCP傳輸協(xié)議規(guī)定了通信雙方需要一個(gè)“連接-接受”這樣的連接確認(rèn)過程,既所謂的三次握手過程。一但連接建立成功,雙方可以通過該連接,進(jìn)行可靠的數(shù)據(jù)通信。
          UDP傳輸協(xié)議不需要雙方進(jìn)行連接,發(fā)送方只需要指定接收方的地址和端口,若接收方此時(shí)正在該端口等待接收,那接收方就有可能(網(wǎng)絡(luò)質(zhì)量不好的話,可能會(huì)丟,不過局域網(wǎng)里通常不會(huì)發(fā)生這樣的情況)收到消息。
          除此之外,還有一個(gè)重要的概念是廣播,將數(shù)據(jù)包發(fā)送到廣播地址(用UDP協(xié)議發(fā)送),則該網(wǎng)段的所有用戶,都可以收到這條數(shù)據(jù)。
          飛鴿協(xié)議分析
          飛鴿的協(xié)議也屬于應(yīng)用層協(xié)議,它描述了飛鴿程序通信時(shí)的語法和語義。
          其語法定義如下(所有的命令字,都必需符合這樣的格式要求):
          Ver(1): PacketNo:SenderName:SenderHost:CommandNo:AdditionalSection
          每部分分別對應(yīng)為:版本號(現(xiàn)在是1):數(shù)據(jù)包編號:發(fā)送主機(jī):命令:附加數(shù)據(jù)
          其中:
          數(shù)據(jù)包編號,一般是取毫秒數(shù)。利用這個(gè)數(shù)據(jù),可以唯一的區(qū)別每個(gè)數(shù)據(jù)包;
          SenderName指的是發(fā)送者的昵稱(m8飛鴿被我統(tǒng)一的寫死為m8,現(xiàn)在知道怎么定制了吧?);
          發(fā)送主機(jī),指的是發(fā)送主機(jī)的主機(jī)名;
          命令,指的是飛鴿協(xié)議中定義的一系列命令,具體見下文;
          附加數(shù)據(jù),指的是對應(yīng)不同的具體命令,需要提供的數(shù)據(jù),具體見下文。
          上面介紹了數(shù)據(jù)包的語法,即格式,這些命令都是通過UDP協(xié)議向其它主機(jī)發(fā)送的。
          接下來列出協(xié)議的命令,包括命令字及附加選項(xiàng):
               1) Command functions (Low 8 bits from command number 32 bits)
                  IPMSG_NOOPERATION        No Operation
                  IPMSG_BR_ENTRY                Entry to service (Start-up with a Broadcast command)
                  IPMSG_BR_EXIT                Exit from service (End with a Broadcast command)
                  IPMSG_ANSENTRY                Notify a new entry
                  IPMSG_BR_ABSENCE        Change absence mode
                  IPMSG_BR_ISGETLIST        Search valid sending host members
                  IPMSG_OKGETLIST                Host list sending notice
                  IPMSG_GETLIST                Host list sending request
                  IPMSG_ANSLIST                Host list sending
                  IPMSG_SENDMSG                Message transmission
                  IPMSG_RECVMSG                Message receiving check
                  IPMSG_READMSG                Message open notice
                  IPMSG_DELMSG                Message discarded notice
                  IPMSG_ANSREADMSG        Message open confirmation notice(added from version-8)
                  IPMSG_GETFILEDATA        File Transfer request by TCP
                  IPMSG_RELEASEFILES        Discard attachment file
                  IPMSG_GETDIRFILES        Attachment hierarchical file request
                  IPMSG_GETINFO                Get IPMSG version info.
                  IPMSG_SENDINFO                Send IPMSG version info.
                  IPMSG_GETABSENCEINFO        Get absence sentence
                  IPMSG_SENDABSENCEINFO        Send absence sentence
                  IPMSG_GETPUBKEY                RSA Public Key Acquisition
                  IPMSG_ANSPUBKEY                RSA Public Key Response
               2) Option flag (High 24 bits from command number 32 bits)
                  IPMSG_ABSENCEOPT        Absence mode(Member recognition command)
                  IPMSG_SERVEROPT                Server(Reserved)
                  IPMSG_DIALUPOPT                Send individual member recognition command
                  IPMSG_SENDCHECKOPT        Transmission check
                  IPMSG_SECRETOPT                Sealed message
                  IPMSG_READCHECKOPT        Sealed message check(added from ver8)
                  IPMSG_PASSWORDOPT        Lock
                  IPMSG_BROADCASTOPT        Broadcast message
                  IPMSG_MULTICASTOPT        Multi-cast(Multiple casts selection)
                  IPMSG_NEWMUTIOPT        New version multi-cast(reserved)
                  IPMSG_AUTORETOPT        Automatic response(Ping-pong protection)
                  IPMSG_NOLOGOPT                No log files
                  IPMSG_NOADDLISTOPT        Notice to the members outside of BR_ENTRY
                  IPMSG_FILEATTACHOPT        File attachment
                  IPMSG_ENCRYPTOPT        Code
                  IPMSG_NOPOPUPOPT        (No longer valid)
                  IPMSG_RETRYOPT                Re-send flag(Use when acquiring HOSTLIST)
               3) Extended code flag (hex format combination)
                  IPMSG_RSA_512
                  IPMSG_RSA_1024
                  IPMSG_RSA_2048
                  IPMSG_RC2_40
                  IPMSG_RC2_128
                  IPMSG_RC2_256
                  IPMSG_BLOWFISH_128
                  IPMSG_BLOWFISH_256
                  IPMSG_SIGN_MD5
               4) Extended files for attachment (fileattr low 8 bits)
                  IPMSG_FILE_REGULAR
                  IPMSG_FILE_DIR
                  IPMSG_FILE_RETPARENT
                  IPMSG_FILE_SYMLINK
                  IPMSG_FILE_CDEV
                  IPMSG_FILE_BDEV
                  IPMSG_FILE_FIFO
                  IPMSG_FILE_RESFORK
               5) Attachment file extended attribute(fileattr high 24 bits)
                  IPMSG_FILE_RONLYOPT
                  IPMSG_FILE_HIDDENOPT
                  IPMSG_FILE_EXHIDDENOPT
                  IPMSG_FILE_ARCHIVEOPT
                  IPMSG_FILE_SYSTEMOPT
               6) Extended file attribute for attachment file
                  IPMSG_FILE_UID
                  IPMSG_FILE_USERNAME
                  IPMSG_FILE_GID
                  IPMSG_FILE_GROUPNAME
                  IPMSG_FILE_PERM
                  IPMSG_FILE_MAJORNO
                  IPMSG_FILE_MINORNO
                  IPMSG_FILE_CTIME
                  IPMSG_FILE_MTIME
                  IPMSG_FILE_ATIME
                  IPMSG_FILE_CREATETIME
                  IPMSG_FILE_CREATOR
                  IPMSG_FILE_FILETYPE
                  IPMSG_FILE_FINDERINFO
                  IPMSG_FILE_ACL
                  IPMSG_FILE_ALIASFNAME
                  IPMSG_FILE_UNICODEFNAME
          基于上面介紹的內(nèi)容,我們可以判斷:
          1:100:shirouzu:jupiter:32:Hello 表示 shirouzu用戶發(fā)送了 Hello 這條消息(32對應(yīng)為IPMSG_SEND_MSG這個(gè)命令,具體需要看源碼中的宏定義)。
          ==========================================
          以下內(nèi)容未完待續(xù),困了,明天再寫
          好,接下來我們進(jìn)入具體場景的分析:
          登錄/離線通知
          登錄過程需要實(shí)現(xiàn)向局域網(wǎng)內(nèi)的用戶廣播,告訴他們,“我來也!”。收到這條消息的用戶則立即回復(fù),“知道了,我在這里”,同時(shí)將新登錄的用戶加入到用戶列表中。發(fā)送方也可根據(jù)收到的回復(fù)信息,了解到當(dāng)前網(wǎng)絡(luò)中,都有哪些已經(jīng)登錄了的用戶。
          具體的數(shù)據(jù)包如下:
          登錄方(要發(fā)送到廣播地址,如255.255.255.255):
          1:XXX:m8:<主機(jī)名稱>:IPMSG_BR_ENTRY:
          接收方回復(fù)(發(fā)送到發(fā)送方的IP地址):
          1:XXX:<接收方主機(jī)名>:IPMSG_ANSENTRY:
          相應(yīng)的,用戶離線時(shí),應(yīng)向廣播地址發(fā)送,“我去也!”,收到這條消息的用戶,需要將發(fā)送方從自己的用戶列表中移除,并且不需要回復(fù)。
          具體的數(shù)據(jù)包如下:
          即將離線用戶:
          1:XXX:m8:<主機(jī)名稱>:IPMSG_BR_EXIT:
          發(fā)送/接收消息
          發(fā)送消息是飛鴿協(xié)議中最重要的部分,通過和一些命令選項(xiàng),可以實(shí)現(xiàn)復(fù)雜的功能:
          最基本的情況下,發(fā)送方通過 IPMSG_SEND_MSG 命令,可以將消息發(fā)送到接收方
          1:12345:m8:<主機(jī)名稱>:IPMSG_SEND_MSG:你好,飛鴿
          使用命令時(shí),“附加數(shù)據(jù)”開使發(fā)揮作用了它里面包含了要發(fā)送的消息。
          通常情況下,由于UDP的不可靠性,還需要為 IPMSG_SEND_MSG 命令設(shè)定 IPMSG_SENDCHECKOPT選項(xiàng),也就是要求接收方回復(fù)回執(zhí)信息。
          1:12345:m8:<主機(jī)名稱>:IPMSG_SEND_MSG|IPMSG_SENDCHECKOPT:你好,飛鴿
          接收方收到IPMSG_SEND_MSG時(shí),如果遇到IPMSG_SENDCHECKOPT選項(xiàng),就要立即回復(fù)如下信息:
          1:XXX:<用戶名>:<主機(jī)名>:IPMSG_RECVMSG:12345
          IPMSG_RECVMSG命令通過附加數(shù)據(jù)段中的數(shù)據(jù)(12345),告訴發(fā)送方,我收到了你的編號為12345的消息包。
          除了上面介紹的IPMSG_SENDCHECKOPT選項(xiàng),飛鴿還支持加密得選項(xiàng),現(xiàn)有的m8版本沒有實(shí)現(xiàn)該功能,所以暫不對這一塊進(jìn)行介紹。
          發(fā)送/接收文件
          文件的傳輸,要稍微復(fù)雜一些,它是通過 IPMSG_SEND_MSG 命令與 IPMSG_FILEATTACHOPT選項(xiàng)的組合,通知接收方“現(xiàn)在有文件要發(fā)給你了”,同時(shí)要將一些描述文件屬性的數(shù)據(jù)(如文件名、大小、創(chuàng)建時(shí)間、類別屬性如文件夾),發(fā)送給接收方,具體格式如下:
          file1ID:filename:size:mtime:fileattr[:extend-attr=val1[,val2...][:extend-attr2=...]]:\a:file2ID...
          這里需要注意的有幾點(diǎn),第一,一條文件傳送命令,可以攜帶多條文件信息;第二,多個(gè)文件信息之前,要用\a分割;第三,size, mtime和fileattr 是用十六進(jìn)制數(shù)描述的);第四,如果文件名中包含“:”,則需要將其轉(zhuǎn)義為“::”。
          相應(yīng)的,接收方收到文件傳送命令后,首先需要從文件屬性的數(shù)據(jù)中解析出要接收的文件的屬性。然后向發(fā)送方相同的端口進(jìn)行TCP連接,連接成功后,通過TCP通道向發(fā)送方發(fā)送IPMSG_GETFILEDATA命令用于接收文件或發(fā)送IPMSG_GETDIRFILES命令,用于接收文件夾。具體接收文件的命令如下:
          1:XXX:m8:<主機(jī)名>:IPMSG_GETFILEDATA:packetID:fileID : offset
          這條命令通過packetID,讓發(fā)送方明白對方請求的文件是源于哪個(gè)命令包;通過fileId讓發(fā)送方確定要發(fā)哪個(gè)文件;通過offset;讓發(fā)送方明白要從哪個(gè)字節(jié)開始發(fā)送。
          發(fā)送方的TCP通道收到上面的命令,就會(huì)發(fā)送對方請求的文件;而接收方將收到的數(shù)據(jù)保存到磁盤上即可。

          posted on 2009-05-07 10:30 suprasoft Inc,. 閱讀(2854) 評論(0)  編輯  收藏 所屬分類: Misc.
          ©2005-2008 Suprasoft Inc., All right reserved.
          主站蜘蛛池模板: 文成县| 合阳县| 德州市| 韶关市| 西平县| 深水埗区| 茌平县| 阜阳市| 聊城市| 仙桃市| 绥宁县| 白朗县| 吉木乃县| 贵南县| 扎兰屯市| 迁西县| 伊通| 乃东县| 吴川市| 池州市| 临猗县| 阿坝县| 鄢陵县| 镶黄旗| 澄城县| 长丰县| 吴桥县| 化州市| 思茅市| 三门峡市| 仲巴县| 九江市| 灌阳县| 北京市| 泗阳县| 启东市| 莱芜市| 旺苍县| 钟山县| 开平市| 玉山县|