私はJavaサーバーとAndroidクライアントを持っています。クライアントはTCPソケットを介してサーバーに3つのものを送信します。1 つ目は int のファイル サイズ、2 つ目はシリアル番号である long、3 つ目は while ループを使用して pdf ファイルを送信します。
3 つのファイルはすべてサーバーに正常に送信されますが、これを行うには、while ループの直後に両側で出力ストリーム (BufferedOutputStream) を閉じる必要があります。これを行わないと、サーバーに送信される PDF ファイルが不完全になり、破損します。また、プログラムはサーバーのwhileループでブロックまたは凍結され、プログラムの実行は行われなくなります。
問題は、ソケットも閉じるクライアントの出力ストリームを閉じた後、サーバーからクライアントに応答を返すことができないことです。また、クライアント側で新しい入力ストリームを開いてこの応答を受け取ることもできません。
20 の異なる Android クライアントがあるため、サーバーは接続する Android クライアントごとに個別のソケット オブジェクトを起動するため、戻りメッセージが目的の正しいクライアントに確実に返されるようにするには、同じソケットが必要です。
ソケットを開いたままにするにはどうすればよいですか? それでも完全なファイルを送信できますか?
while ループを示すサーバー コードのサンプル
@Override
public void run() { // launch new thread
fileSizeFromClient = dis.readInt();
serialNumber = dis.readLong();
byte[] buffer = new byte[fileSizeFromClient];
while((count = dis.read(buffer)) > 0){
bos.write(buffer, 0, count);
}
bos.close();
} // end thread
while ループを示すクライアント コードのサンプル
@Override
public void run() { // launch new thread
dos.writeInt((int)length); // sends the length as number bytes is file size
dos.writeLong(serial);
int count = 0; // number of bytes
while ((count = bis.read(bytes)) > 0) {
dos.write(bytes, 0, count);
}
dos.flush();
dos.close();
} // end thread
観察:
1 - BufferedOutputStream または DataOutputStream オブジェクトのいずれかで close() を呼び出すと、ソケットが閉じられます
2 - クライアントで outputStream.close() が呼び出されない場合、サーバー コードでは while ループでスタックまたはハングし、スレッドの実行は続行されず、ブロックされ、送信された pdf ファイル不完全で破損します
3 - サーバーで outputSteam.close() が呼び出されない場合、上記の 2 のようにサーバー コードがブロックされたりスタックしたりすることはありませんが、送信された pdf ファイルは不完全または破損して到着します。
4 - クライアントとサーバーの両方の出力ストリームで、それぞれの while ループの直後に close() が呼び出された場合、クライアントでもサーバーでも、プログラムの実行にブロックや問題は発生しません。PDFファイルは常に良好な状態で届きます。
編集:私はこれについて完全に間違った方向に進んでいますか? PDFファイルを送信した後にソケットを閉じて、新しいソケットを開いた方が良いですか? その場合、以前のソケットが接続されていたのと同じ Android クライアントで開く方法。他のクライアントではなく、同じ Android クライアントに応答メッセージを送り返したい。