<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 56,  comments - 12,  trackbacks - 0

    網絡協議基本的通訊單位是一個一個的消息包。在用socket傳輸這些包的時,首先要解決的一個問題是如何解決包與包之間的邊界問題。socket 傳輸的是流,一個send中發出的消息,在對方不一定在一個recv中收到,可能要多次recv,或者一個recv收到多個send中放出的包。所以必須 由應用層協議自己來解決包的定界問題。通常有兩種方法,一種是每個包以一個特殊的字符或者字符串來結束,如http協議就是以兩個'\n'作為一個消息的 結束標記;另一種方法就是,所有的消息都有一個固定長度的消息頭,在消息頭中指出這條消息的長度。我們的協議是采用第二種方法,這也是大部分協議采用的方 法。本文提出的框架也是解決這種協議方式的。
    Java的New IO是在J2SE1.4引入的,主要引入了Buffer這樣的概念,發送接受數據都是在Buffer上進行,而對于初學者,Buffer的操作是比較復雜的,容易出錯。所以在這個框架中盡可能的把對于Buffer的操作封裝起來。
    框架主要有MessageHeader, Message, MessageFactory三個接口,兩個類MessageChannel, BufferUtil,以及一個異常類MessageFormatException構成。下面說明這幾個接口和類的功能。

    1. MessageHeader接口
    在這樣一套網絡協議中,總是有一個固定長度的消息頭,不同的協議有不同的消息頭,但是幾乎所有的消息 頭都定義了本消息的長度和本消息的類型。類型用于識別不同的消息包。類型相同的包,格式都是一樣的,可以用同一個Java的class來表達。類型不同的 包,格式可能相同也可能不同,依賴于協議。接口定義如下:
    public interface MessageHeader {
     /**
      * 返回消息類型
      */
     int getMessageType();
     
     /**
      * 返回消息長度
      */
     int getMessageLength();

     /**
      * 從Buffer中提取消息頭
      */
     void buildFromBuffer(ByteBuffer buffer);

     /**
      * 把消息頭放到Buffer中
      */
     void appendToBuffer(ByteBuffer buffer);
     
    }

    2. Message接口
    Message代表一個消息包。每個消息包有一個消息頭。其定義如下:
    public interface Message {
     /**
      * 設置消息頭,在MessageChannel.receive中調用
      */
     void setHeader(MessageHeader header);

     /**
      * 返回消息頭
      */
     MessageHeader getHeader();

     /**
      * 從Buffer中取出消息體
      */
     void buildBodyFromBuffer(ByteBuffer buffer);
     
     /**
      * 把消息體放到Buffer中
      */
     void appendBodyToBuffer(ByteBuffer buffer);
    }

    3. MessageFactory接口
    這個接口封裝了所有真正的用于表達消息的類的創建,在MessageChannel的receive中調用。這里用了抽象工廠模式。其定義如下:
    public interface MessageFactory {
     /**
      * 返回消息頭的字節數
      */
     int getMessageHeaderLength();
     
     /**
      * 創建一個消息頭對象
      */
     MessageHeader createMessageHeader();

     /**
      * 創建一個消息對象
      * @param type 消息類型,從消息頭中取得
      */
     Message createMessage(int type);
    }

    4. MessageChannel類
    主要功能都在這個類中,用于發送和接收消息,并封裝了所有對于Buffer的操作。
    class MessageChannel {
    /**
     * 構造方法,要求指明發送緩沖區和接收緩沖區的大小
     */
    public MessageChannel(int receiveBufferSize,
       int sendBufferSize,
       SocketChannel sc,
       MessageFactory mf);
    /**
     * 接收一條消息,當消息不完整、收到的消息長度太大(超過接收緩沖區大小)或者不能通過MessageFactory創建的消息類型時時拋出MessageFormatException。
     */
    public Message receive() throws IOException, MessageFormatException;

    /**
     * 發送一條消息
     */
    public void send(Message message) throws IOException;

    }

    5. BufferUtil類
    這是一個Utility類,主要功能是從ByteBuffer中取得或者放入一個字符串String,不同的協議有不同的字符串處理方法。
    class BufferUtil {
     /**
      * 從buffer取得一個字符串,length為長度
      */
     static String getString(ByteBuffer buffer, int length);
     
     /**
      * 從buffer取得一個以'\0'結束的字符串,length為最大長度
      */
     static String getCString(ByteBuffer buffer, int length);
     
     /**
      * 從buffer取得一個變長的字符串,長度用兩字節的short類型表示
      */
     static String getVarStringShortLength(ByteBuffer buffer);

     /**
      * 從buffer取得一個變長的字符串,長度用四字節的int類型表示
      */
     static String getVarStringIntLength(ByteBuffer buffer);

     /**
      * 從buffer取得一個變長的字符串,長度用一字節的byte表示
      */
     static String getVarStringByteLength();
     
     /**
      * 在buffer中放入一個字符串,length為長度
      */
     static void putString(ByteBuffer buffer, String str, int length);

     /**
      * 在buffer中放入一個字符串,length為最大長度。如果str沒有達到最大長度,那么用0填充。
      */
     static void putCString(ByteBuffer buffer, String str, int length);
     
     /**
      * 在buffer中放入一個字符串,長度用一個short表示
      */
     static void putVarStringShortLength(ByteBuffer buffer);
     
     /**
      * 在buffer中放入一個字符串,長度用一個int表示
      */
     static void putVarStringIntLength(ByteBuffer buffer);
     
     /**
      * 在buffer中放入一個字符串,長度用一個byte表示
      */
     static void putVarStringByteLength(ByteBuffer buffer);
    }
    目前,這個類沒有考慮編碼方式,可以對這個類進行擴充。

    在這個框架中,Message.receive是最復雜的部分,下面對該過程的流程進行說明:
    (1) 根據MessageFactory.getMessageHeaderLength()返回的消息頭長度,接收消息頭。
    (2) 用MessageFactory.createMessageHeader() 構造消息頭,并調用MessageHeader.buildFromBuffer()取得消息頭數據。
    (3) 根據消息頭中的信息,接收消息體
    (4) 構造消息,并調用Message.buildBodyFromBuffer()取得消息體數據。
    (5) 調用Message.setHeader()。
    (6) 返回構造的消息。
    這其中有一個步驟出錯,將拋出MessageFormatException。

    posted on 2007-01-18 23:53 苦笑枯 閱讀(632) 評論(0)  編輯  收藏 所屬分類: Java
    收藏來自互聯網,僅供學習。若有侵權,請與我聯系!

    <2007年1月>
    31123456
    78910111213
    14151617181920
    21222324252627
    28293031123
    45678910

    常用鏈接

    留言簿(2)

    隨筆分類(56)

    隨筆檔案(56)

    搜索

    •  

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 美女视频黄的全免费视频| 国产色无码精品视频免费| 国产一卡二卡四卡免费| 久久精品国产亚洲av麻| 永久在线观看免费视频| 亚洲AV无码一区二区二三区入口 | 人人爽人人爽人人片A免费| 免费永久在线观看黄网站| 爱情岛论坛免费视频| 亚洲日韩人妻第一页| 日本免费高清视频| 亚洲理论片中文字幕电影| 91在线品视觉盛宴免费| 亚洲欧洲免费无码| 四虎影永久在线高清免费| a级毛片免费观看在线| 国产亚洲一区二区精品| 久久永久免费人妻精品下载| 亚洲国产高清美女在线观看| 久久精品女人天堂AV免费观看| 在线观看免费亚洲| 亚洲国产精品毛片av不卡在线| 国产线视频精品免费观看视频| 亚洲嫩草影院久久精品| 成在人线AV无码免费| 污网站在线免费观看| 亚洲αv久久久噜噜噜噜噜| 99久久免费国产香蕉麻豆| 亚洲1区2区3区精华液| 国产成人麻豆亚洲综合无码精品| 一级毛片不卡片免费观看| 亚洲日韩AV一区二区三区四区| 亚洲国产午夜福利在线播放| 一级毛片免费不卡在线| 亚洲av无码专区亚洲av不卡| 精品国产_亚洲人成在线高清 | 亚洲国产精品第一区二区三区 | 免费观看男人免费桶女人视频| 午夜免费国产体验区免费的| 亚洲久本草在线中文字幕| 日本一道综合久久aⅴ免费|