0

新しいスレッドを起動する run メソッドがあり、終了後にそこから別のメソッドを起動したいのですが、これは機能していません。メソッドの最後にいくつかの印刷ステートメントを入れましたが、最初にJavaプログラムをロードしたときのように数回しか表示されません。通常は表示されません。

それらが表示されない理由を知りたかったのですが、Java スレッドで使用できる AsyncTask の onPostExecute() などのコールバック メソッドのような信頼できる方法があります。

印刷ステートメントが 98% の確率で表示されない理由がわかりません。何か案は?

ここで少し混乱。ファイルがwhileループの最後とカウント変数に到達し、0または-1になると思ったので、whileループが終了し、プロセスの実行が終了し、whileループを終了して続行しますスレッド。これは起こっておらず、意味がありません。

このコードで受信しているファイルは完成しており、問題はありません。ただし、別のスレッド メソッドを起動して Android クライアントにメッセージを送り返し、ファイルが正常に受信されたことを伝える必要があります。

残りのコード

 @Override
public void run() {

    FileOutputStream fos = null;
    BufferedOutputStream bos = null;
    BufferedInputStream bis = null;
    DataInputStream dis = null;
    int bufferSize = 0;

    File file = new File("/Users/UserName/sampleFile.db");

    // get input streams
    try {
    fos = new FileOutputStream(file);
    bos = new BufferedOutputStream(fos);
    bis = new BufferedInputStream(socket.getInputStream());
    dis = new DataInputStream(bis);
    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    try {
        bufferSize = socket.getReceiveBufferSize();
    } catch (SocketException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    int fileSizeFromClient = 0;
    long serialNumber = 0;

    try {
        fileSizeFromClient = dis.readInt();
        serialNumber = dis.readLong();
    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    String serialString = String.valueOf(serialNumber);

    System.out.println("filesize " + fileSizeFromClient);
    System.out.println("serialNumber " + serialString);
    System.out.println("bufferSize " + bufferSize);

    int count = 0;
    try {
        bos.flush();
    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
    }

    byte[] buffer = new byte[fileSizeFromClient];
    try {
        while((count = dis.read(buffer)) > 0){
            bos.write(buffer, 0, count);

           if(count == -1){ // <-- this line does not help break out of loop
             break;
            }


        }

        System.out.println("size of file written " + buffer.length); // <-- does not print out
        socket.close();

        System.out.println("test out 1"); // <-- does not print out

    } catch (IOException ex) {
        Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);

     } catch (Exception ex) {
            Logger.getLogger(MultiThreader.class.getName()).log(Level.SEVERE, null, ex);
        }

  System.out.println("test out 2"); // <-- does not print out

}  // end run

編集:これはAndroidではなくJavaデスクトップアプリ用であることを忘れていましたが、接続先のクライアントはAndroidデバイスです。ファイル、ソケット、および TCP/IP ファイルの送受信に問題はありません ネットワークには問題はありません

4

1 に答える 1

2

質問に対する答えを見つけました。

Java サーバーが次の行でスタックまたはハングします。

  while((count = dis.read(buffer)) > 0){
        bos.write(buffer, 0, count);

サーバーが接続されている Android クライアントの outputStream オブジェクトのためです。次のようにクライアントで outputStream を閉じると:

 dos.close();   // for DataOutputStream dos;

クライアントの InputStream オブジェクトは効果がなく、OutputStream のみです。クライアントの OutputStream が for ループの直後に閉じられると、for ループでの Java サーバーのブロックまたはハングが停止します。

Android クライアントからのコード

   while ((count = bis.read(bytes)) > 0) {
          dos.write(bytes, 0, count);
         }
             dos.close();

この調整の後、for ループの後の Java サーバーのすべての System.out.println ステートメントが機能するようになりました。run メソッドの最後の行まで。

于 2013-09-23T13:59:42.170 に答える