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();

1 つの質問は、ループがファイルの最後で止まらないのはなぜですか? 2 番目の質問は、なぜ も非常に遅いのかということです。

4

2 に答える 2

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 レベルのネットワーク バッファーがその仕事を実行できるようになり、データをできるだけ少ないパケットに分割できます。

于 2010-12-08T08:00:34.187 に答える
2

2 番目の質問 - クライアントは raw ソケット ストリームから直接バイトを読み取ります。BufferedInputStream/BufferedOutputStream デコレータを使用すると、パフォーマンスが向上します。

サーバ側

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

クライアント側

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

生のストリームはバッファリングされていない (AFAIK) ため、必要に応じて手動でバッファリングを追加する必要があります。

于 2010-12-08T08:01:02.747 に答える