2010-09-15 15 views
1

我有一些代碼:ReadableByteChannel.read(ByteBuffer dest)以8KB讀取上限。爲什麼?

  1. ReadableByteChannel讀入一個ByteBuffer
  2. 取字節轉移的筆記,
  3. 暫停幾十到幾百毫秒的,
  4. 通行證ByteBuffer轉化爲WritableByteChannel

一些細節:

  • 兩個通道,TCP/IP套接字。
  • 總連接讀取大小爲幾十兆字節。
  • 源套接字(其中ReadableByteChannel從中獲取字節)位於同一臺計算機上。
  • Debian的萊尼在HP DL380s 64位
  • 的Sun Java 1.6.0更新20

的問題是,無論字節緩衝區是如何分配的大,要麼.allocate().allocateDirect(),字節數讀入8KB的ByteBuffer maxes。我的目標ByteBuffer大小是256KB,這只是一小部分(第1/32nd)被使用。大約10%的時間只有2896字節被讀入。

我檢查了操作系統的TCP緩衝區設置,它們看起來很好。通過觀察netstat報告緩衝區中有多少字節的報告證實了這一點 - 兩個套接字緩衝區中的數據都超過了8KB。

tcp  0 192384 1.2.3.4:8088  1.2.3.4:53404 ESTABLISHED 
tcp6 110144  0 1.2.3.4:53404 1.2.3.4:8088  ESTABLISHED 

這裏有一件事是TCP和TCP6的混合,但我認爲這應該不是問題。我的Java客戶端位於上述輸出中的端口53404上。

我試過設置套接字屬性來支持帶寬超過延遲,但沒有改變。

Socket socket = new Socket(host.getHostName(), host.getPort()); 
socket.setPerformancePreferences(1, 0, 2); //bw > connection time > latency 

當我登錄的socket.getReceiveBufferSize()值時,它始終報告僅43856個字節。雖然它比我想要的小,但它仍然超過8KB。 (這也不是一個非常圓的數字,我會預料到的。)

我真的難以理解問題出在哪裏。理論上說,AFAIK,這不應該發生。將「降級」爲基於流的解決方案並不理想,但如果找不到解決方案,那麼我們就會去下一個解決方案。

我錯過了什麼?我能做些什麼來糾正它?

回答

0

好的,我發現了這個問題! (和我回答我的問題,以防有人有同樣的問題。)

我是不是直接從Socket實例實例化的ReadableByteChannel,而是從該HttpEntity.getContent()Apache HTTP Commons Client)方法的返回InputStream。早期的HTTP Commons客戶端已經通過了DefaultHttpClientConnection.bind()方法。我不明白的是,我認爲該頻道是埋在HTTP Commons Client實施中的BufferedInputStream實例。 (8KB恰好是Java 6的默認值)。

因此,我的解決方案是從原始Socket實例中獲取ReadableByteChannel