0

ファイルを受け入れ、DataInputStreamとBufferedInputStreamを使用して特定のディレクトリに書き込むサーバーを作成しようとしています。

サーバーは'ユーザー名(文字列)''ファイル数(int)''ファイル名(文字列)''各ファイルのサイズ(long)'および'解釈されないファイルの内容bytes(byte [])'を取得します

そして、すべてが成功した場合、私はブール値を送信することになっています。

しかし、問題は、ファイルを正しく受信していないことです。

時々、「壊れたパイプ」エラーメッセージが表示されたり、受信後にファイルが破損したりします。

コードを4時間調べましたが、問題は見つかりませんでした。

これについて教えていただけませんか?クライアントは正常に動作していると想定できます。

4

1 に答える 1

2

まず、これらのストリームをすべて閉じる必要はありません。それがおそらく、壊れたパイプの問題を見ている理由です。入力ストリームと出力ストリームを閉じるだけです。

DataInputStream din = new DataInputStream( new BufferedInputStream( socket.getInputStream() ) );
DataOutputStream dout = new DateOutputStream( new BufferedOutputStream( socket.getOutputStream() );
try {


} finally {
   din.close();
   dout.close();
}

これらのストリームをすべて閉じる必要がない理由は、din/dout.close() が呼び出されたときに Buffered*Streams とソケットの InputStream/OutStream が閉じられるためです。これらは、チェーン先の参照を介してストリームを閉じます。また、if( blah != null ) ジャンクをすべて取り除くこともできます。なぜなら、finally 句にたどり着けば、null でないことがわかるからです。あなたが試してみない限り、それは事実です。

2 番目の新しい FileOutputStream() で fos 変数を上書きしたため、FileOutputStream もリークしています。SUBMIT_DONE ファイルで何をしていますか? それは本当に奇妙です。それをするのはかなり悪い考えです。そのように変数参照を 2 回使用しないでください。おそらく、ループの後に最初のファイルを閉じます。そのループを try {} finally { fos.close(); でラップすることを考えてください。}。

そして、これを少し分解する方法を使用してみてください。静的を捨てます。

アップデート:

以下は正確に何をしていると思いますか?

while(c!='\0') {
   userName += c;
   c = din.readChar();
}

クライアントまたはサーバーからデータを送信する方法に応じて、次を使用できます。

String userName = din.readUTF();

DataInputStream を使用して、フォーマットされた BINARY データを処理していることを思い出してください。また、ファイル名に対してその正確なループ コードが再度繰り返されます。readUTF() を使用できない場合は、そのループをラップして文字列を返すメソッドを作成し、それらの 2 つの場所から呼び出します。クライアントが未加工のファイル名とファイルをアップロードできるようにする、あらゆる種類のセキュリティ上の問題があります。あなたが構築しているこのサーバーが本番環境にデプロイされていないことを願っています。

また、ソケットを介して受信した各ファイルをフラッシュして閉じる必要があるため、送信されたデータの全量がファイルに完全に書き込まれます。

于 2011-10-07T03:49:33.893 に答える