2

いくつか質問があります-

1. ソケット接続で接続された 2 台のコンピュータがあります。プログラムの実行時

outputStream.writeInt(value);
outputStream.flush();

実際にはどうなりますか?プログラムは、他のコンピューターが整数値を読み取るまで待機しますか?

2.outputStreamまたはを空にするにはどうすればよいinputStreamですか? outputStreamつまり、 orを空にすると、inputStreamそのストリームに書き込まれたものはすべて削除されます。(接続を閉じることを提案しないでください!)inputStreamこの方法で空にしようとしました-

byte[] eatup=new byte[20*1024];
int available=0;
while(true)
{
    available=serverInputStream.available();
    if(available==0)
       break;
    serverInputStream.read(eatup,0,available);
}
eatup=null;

String fileName=(String)serverInputStream.readObject();

には他に何も書かれていないので、プログラムはその行を処理すべきではありませんoutputStream。しかし、私のプログラムはとにかくそれを実行し、java.io.OptionalDataExceptionエラーをスローします。

注:私はクライアント サーバー ファイル転送プロジェクトに取り組んでいます。クライアントはファイルをサーバーに送信します。2 番目のコードはサーバー端末用です。サーバー側で「キャンセルボタン」が押された場合、からのバイトの読み取りを停止し、クライアントserverInputStreamにシグナル (私はint -1 を使用) を送信します。クライアントがこのシグナルを受信すると、サーバーへのデータの送信を停止しますが、それがserverInputStream空ではないことに気付きました。serverInputStreamしたがって、クライアントコンピューターがサーバーコンピューターのファイルを再度送信できるように、これを空にする必要があります(そのため、readメソッドからロックを管理できません)

4

1 に答える 1

2

1-いいえ。flush()では、データはOSカーネルに書き込まれ、OSカーネルはすぐにネットワークカードドライバーにデータを渡し、ネットワークカードドライバーはデータを受信側に送信します。一言で言えば、送信はファイアアンドフォーゲットです。

2-ジェフリーがコメントしたように、available()はこの種の操作には信頼できません。ブロッキングIOを実行する場合は、彼が示唆しているように、投機的にread()を使用する必要があります。ただし、DataInput / DataOutputStreamを使用している場合でも、生のストリームの上にプロトコルを定義する必要があると言っておく必要があります。生の書き込み/読み取りを使用する場合、黄金律は1回の書き込み!=1回の読み取りです。たとえば、一方の側に10バイトを書き込み、もう一方の側に読み取りループがある場合、1回の読み取りで10バイトすべてが読み取られる保証はありません。チャンクの任意の組み合わせとして「読み取られる」場合があります。同様に、10バイトの2回の書き込みは、受信側で20バイトの1回の読み取りとして表示される場合があります。言い換えれば、パケットを実行するために生のバイトの上に高レベルのプロトコルを作成しない限り、「パケット」の概念はありません。

基本的なアプリよりも複雑なことを行う必要がある場合は、ネットワークIOの厄介な問題の多くを解決したいくつかの高レベルのライブラリを調査することを強くお勧めします。本番アプリに使用しているNettyをお勧めします。ただし、単純なIOストリームからNettyのよりイベントベースのシステムへの理解には大きな飛躍があります。途中に他のライブラリがあるかもしれません。

于 2012-09-02T18:11:03.073 に答える