2010-12-08 12 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(); 

一つ質問です:ループはで停止しないのはなぜファイルの最後? 2番目の質問は、なぜそんなに遅いのでしょうか?

答えて

4

あなたが本当に安全になりたい場合は、サーバーのソースで

if (i == 1) { 

if (i == -1) { 

か、する必要がありますので、それは停止しません:

if (i <= 0) { 

また、あなたのリスクこの行のデータ破損:

パフォーマンスに

os.write(mybytearray, 0, i); 

- whileループの外にos.flush();コールを移動:

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

あなたはこれを変更する必要があります。ネットワークストリームをフラッシュすると、バッファされたデータがネットワークに送信されます。これは、ネットワーク層に、1024バイトのTCPペイロード(もちろん、より大きなイーサネットペイロード)を送信し、確認することを強制します。これはおそらく、PMTUよりもかなり小さいでしょう。データの送信が完了したとき、またはクライアントにバッファされたデータを受信させたいときは、、今度はにするだけです。各繰り返しからフラッシュ呼び出しを削除すると、OSレベルのネットワークバッファがそのジョブを実行し、データを可能な限り少数のパケットに分割することができます。

+0

ありがとうございました! – hephestos

2

2番目の質問 - クライアントがrawソケットストリームから直接バイトを読み込みます。 BufferedInputStreamを/なBufferedOutputStreamのデコレータを使用し、これは増やす必要があり、パフォーマンス:

サーバー側

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

生のストリームは(私の知る限り)バッファリングされていないので、あなたが持っている

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

クライアント側必要に応じて手動でバッファリングを追加します。

+0

はいこれはいくらかのスピードを追加しました。それはとてもシンプルでした;-)私はそれを自分で見たはずです。いずれにせよ、ありがとう。 – hephestos

関連する問題