熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

網絡數據流的java處理

2013-11-23 19:37:25  來源: Java核心技術 

  郭洪鋒 ()該文章對編寫客戶服務器應用的java程序員有所幫助可以解決程序在對方出現故障的時候繼續穩定運行
  前言java程序要處理很多的網絡數據網絡數據發送和接收以及數據流的處理是java程序要特別關注的方面隨著java的發展這些方法也越來越得到重視和加強本文從幾個方面解釋了java正確處理網絡數據流的要素這些也是java程序員必須了解的基本的知識
  
  龐大的java流處理
  首先之所以說java流的龐大是因為java中的流處理比其他語言的流處理在內容上多的多
  
  java流在處理上分為字符流和字節流字符流處理的單元為個字節的Unicode字符分別操作字符字符數組或字符串而字節流處理單元為個字節操作字節和字節數組
  
  Java內用Unicode編碼存儲字符字符流處理類負責將外部的其他編碼的字符流和java內Unicode字符流之間的轉換而類InputStreamReader和OutputStreamWriter處理字符流和字節流的轉換字符流(一次可以處理一個緩沖區)一次操作比字節流(一次一個字節)效率高
  
  對應不同的流需要不同的流構建器或流過濾實現java目前依然在逐漸增加其流處理方法雖然java類庫的創作人員可以列舉出很多理由來說明這要做的優點但我還是覺得java開始變得向其他語言一樣復雜起來
  
  網絡數據流的收發
  java對網絡數據的發送和接收處理也借用了一般流處理的方法我們知道在幾乎其他所有語言中網絡數據的收發在利用類似send(或write)和recv(或read)的方法時並沒有明顯的流處理但是java和這些語言的收發方法有較大區別要借助流才可以完成
  
  
   sock = new Socket(addr port);
  
   OutputStream os = sockgetOutputStream();
  
   InputStream is = sockgetInputStream();
  
   oswrite(byte[] b);
  
   isread(byte[] b);
  
  
  
  這些方法總給人一種不太舒服的感覺不過從Jdk開始彌補了這一點JDK中新增加了新的I/O流處理在緩沖區管理可伸縮網絡和文件IO字符集支持正規表達式匹配方面做了新的處理其中緩沖區管理和通道(Channel)概念則是對網絡數據流的收發處理支持的強化緩沖區管理中ByteBuffer類更好的支持了網絡數據流處理在網絡連接中通道代表了sockets的連接基於這些新的IO處理以上代碼可以改寫為
  
  ByteBuffer bytebuf = ByteBufferallocate(); // 創建一個指定大小的緩沖區
  
  InetSocketAddress isa = new InetSocketAddress(hostnameport);
  
  sc = SocketChannelopen(); // 建立一個socket通道
  
  nnect( isa); // 建立一個socket連接
  
  …
  
  scwrite(bytebuf); // 發送數據
  
  …
  
  scread(bytebuf); // 接收數據
  
  這樣的程序似乎要流暢的多
  
  
  
  java對網絡數據流的處理
  java程序對網絡數據流的處理要關注四個基本方面數據流的編碼字節順序數據格式對應和取數這是四個不同的問題但是都影響到網絡數據的正確接收
  
   網絡數據流的解碼和編碼
  網絡數據流的編碼和解碼主要針對流中出現的字符串網絡數據流中的字符串均為原始的字節流形式
  
  要正確接收網絡數據流中的字符串首先要知道該字符串的編碼方案然後才可以調用解碼的方法獲得java能夠認識的Unicode編碼字符串可以用如下代碼處理網絡數據流中字符串的編碼和解碼
  // 獲得編碼對象即網絡對等方的認識的字符串編碼
  
  Charset charset = CharsetforName(???); // ???為對等方的編碼名java必須支持
  
  // 生成編碼器和解碼器對象
  
  CharsetDecoder decoder = charsetnewDecoder();
  
  CharsetEncoder encoder = charsetnewEncoder();
  
  
  
  // 對從網絡數據流中獲得的字節流解碼取得java字符串
  
  CharBuffer charbuf = decoderdecode(bytebuff);
  
  
  
  // 將java字符串編碼成指定編碼的字節流以便網絡發送
  
  Bytebuff bytebuff = encoderencode(CharBufferwrap(Test String);
  
  
  
  
  
  
   網絡數據流的字節順序
  目前的字節順序有兩類BIG_ENGIAN和LITTLE_ENDIAN各個平台所支持的字節序不同例如AIXTruUnixWindows等操作系統平台采用LITTLE_ENDIAN字節序Solaris等操作系統平台采用BIG_ENGIANJava自身采用的是BIG_ENGIAN字節序當java和運行在其他平台上的其他語言編寫的通信程序通信時則必須考慮到數據的字節序
  
  Jkd新增加的包NIO中的類ByteOrder則帶來了一定的方便針對從網絡數據流的字節序我們只要增加一行就可以輕松的處理字節序了
  bytebuforder(ByteOrderLITTLE_ENDIAN); //按照LITTLE_ENDIAN字節序收發數據
  scread(bytebuf); // 接收數據
  
  上面的方法雖然簡化了我們的編程但沒有真正處理好分布式應用的網絡數據字節序問題例如java同時和在TruUnixSolaris平台上的應用通信時上述方法就不能解決問題因為同一數據包可能無法判斷其字節序是那一種此時要求網絡數據包內攜帶附加的字節序信息顯然是不現實的這種情況下java語言需要提供對XDR(外部數據表達)的支持目前XDR已經為事實上的網絡數據流的標准格式分布式應用的網絡數據流基本都遵循了這種格式如果java語言提供了對XDR的支持就可以解決通用性的問題對於分布式應用中的網絡數據流的處理就無需再根據其平台判斷其字節序只要按照XDR格式進行處理就可以了
  
   網絡數據流中數據格式的對應
  C/C++語言編寫的網絡程序中一般采用數據結構的緩沖區發送數據在java端接收數據時會出現一些因數據組織引起的問題 如結構 typedef struct {
  
  int  id;
  
  char name[];
  
  short val;
  
  float fval;
  
   } SendData
  
  在位操作系統中它的大小並不是而是!數據的組織如下圖所示
  
  當通過網絡發送到客戶端時客戶端也接收到個字節如果按照順序依次取相應的值則會發現最後取得的浮點值不正確這是因為把短整型數據後沒有意義的兩位作為了浮點數中的其中兩位如果想正確接收該數據則必須跳過短整型數據後沒有意義的兩位再取浮點值
  
  而如果以上的結構變為
  typedef struct {
  
  int  id;
  
  char name[];
  
  float fval;
  
  short val;
  
   }
  
  則java端按照順序依次接收數據就不會發生問題
  
  所以在編寫程序時對數據的正確組織也是非常重要的
  
   從網絡數據流中取得需要的數據
  在C/C++的Socket編程時采用數據結構收發數據很方便特別是接收數據時可以由數據結構的數據類型自動獲得網絡數據流相應的數據但是在java中目前我們必須對流進行分析逐一的取得自己所需要的數據並且由於網絡數據流是原始的數據流還要根據程序所需要的數據類型對網絡數據流進行解碼處理發送網絡數據時同樣需要對數據進行封裝這個過程也增加了java程序的煩瑣性例如上述結構要用如下代碼獲取相應數據
  
  int id = bytebufgetInt(); // 獲得整數型值
  int limit = bytebuflimit(); // 獲得字節緩沖區的限值
  bytebuflimit(); // 設置字節緩沖區的限值為字符串後面的第一個字節位置
  CharBuffer charbuf = decoderdecode(bytebuf); // 解碼獲得字符串
  Bytebuflimit(limit); // 恢復字節緩沖區原來的限值
  float fval = bytebufgetfloat(); // 獲得浮點型值
  short val = bytebufgetshort(); // 獲得短整型數值
  結束語
  從上面的介紹可以看出java程序中對網絡數據流的處理涉及的問題較多在編寫網絡程序時必須注意這些問題以使得程序正確的處理通信的內容
  
  參考資料
  
  
  
  關於作者
  郭洪鋒在煙台東方電子信息產業集團公司中心所工作一直從事分布式系統的開發和研究
From:http://tw.wingwit.com/Article/program/Java/hx/201311/27197.html
  • 上一篇文章:

  • 下一篇文章:
  • 推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.