2010-12-08 41 views
1

我有一個Java服務器類是這樣的:插座傳輸文件

ServerSocket servsock = new ServerSocket(63456); 
boolean read = false; 
while (!read) { 
    Socket sock = servsock.accept(); 
    int length = 1024; 
    byte[] mybytearray = new byte[length]; 
    OutputStream os = sock.getOutputStream(); 
    BufferedInputStream bis = new BufferedInputStream(new FileInputStream(myFile)); 
    while (true) { 
    int i = bis.read(mybytearray, 0, mybytearray.length); 
    if (i == 1) { 
     break; 
    } 
    os.write(mybytearray, 0, mybytearray.length); 
    os.flush(); 
    } 
    sock.close(); 
    read = true; 
} 

` 而客戶端是這樣的:

Socket sock = new Socket("127.0.0.1", 63456); 
byte[] mybytearray = new byte[1024]; 
InputStream is = sock.getInputStream(); 
FileOutputStream fos = new FileOutputStream("C:/tmp/NEWtmp.rar"); 
BufferedOutputStream bos = new BufferedOutputStream(fos); 
int bytesRead = is.read(mybytearray, 0, mybytearray.length); 
while(bytesRead != -1) { 
    bos.write(mybytearray, 0, bytesRead); 
    bytesRead = is.read(mybytearray, 0, mybytearray.length); 
} 
bos.close(); 
sock.close(); 

的一個問題是:爲什麼循環不會在停止文件的結尾? 第二個問題是,爲什麼也這麼慢?

回答

4

它不會停下來,因爲

if (i == 1) { 
在您的服務器源

應該

if (i == -1) { 

或者,如果你想成爲真正安全:

if (i <= 0) { 

而且,你的風險此行的數據損壞:

os.write(mybytearray, 0, mybytearray.length); 

你應該更改爲:

os.write(mybytearray, 0, i); 

在性能 - 在os.flush();呼叫轉移到while循環外。當你刷新一個網絡流時,你迫使它將任何緩衝的數據發送到網絡。這迫使網絡層發送並確認1024字節的TCP有效載荷(當然是更大的以太網有效載荷),這可能比PMTU小得多。您只需在發送數據完成後或當您希望客戶端接收緩衝數據(現在爲)時進行刷新。從每次迭代中刪除刷新調用將允許OS級網絡緩衝區完成其工作,並將數據分割成儘可能少的數據包。

+0

謝謝,它工作! – hephestos 2010-12-08 08:16:06

2

第二個問題 - 您的客戶端直接從原始套接字流中讀取字節。使用的BufferedInputStream /的BufferedOutputStream裝飾,這應該提高性能:

服務器端

BufferedOutputStream os = new BufferedOutputStream(sock.getOutputStream()); 

客戶端

BufferedInputStream is = new BufferedInputStream(sock.getInputStream()); 

原始流沒有被緩衝(據我所知),所以你有如果需要,手動添加緩衝。

+0

是的,這增加了一些速度。這很簡單;-)我應該親眼看到它,無論如何,謝謝。 – hephestos 2010-12-08 08:17:44