2011-08-03 5 views
1

私はAndroid用のWebサーバーで作業していますが、これを修正しようと数日間を費やしたにもかかわらず、バグ。私はブラウザからリクエストを読み込もうとしていますが、ほとんどの場合、コードはうまく動作しますが、要求の5%が失敗し、Socketの1文字も読み込まなくてもランダムなSocketTimeoutExceptionsがスローされます。.read()はデータが存在するにもかかわらず断続的なSocketTimeoutExceptionをスローする

私はこれをさまざまなブラウザでテストしましたが、すべてのブラウザでこれがテストされています。問題は私の目的です。

public class ServerThread extends Thread { 

private ServerSocket ss = null; 
private boolean isRunning; 

private ExecutorService threadPool = new ThreadPoolExecutor(2, 12, 
      60L, TimeUnit.SECONDS, 
      new SynchronousQueue<Runnable>(), 
      Executors.defaultThreadFactory(), 
      new ThreadPoolExecutor.CallerRunsPolicy()); 

public ServerThread() { 
} 

public synchronized void run() { 
    ss = new ServerSocket(8080, 1); 
    isRunning = true; 

    while (isRunning) { 
     Socket clientSocket = null; 

     try { 
      if (ss != null) { 
       clientSocket = ss.accept(); 
       if (isRunning) { 
        this.threadPool.execute(new HTTPSession(clientSocket)); 
       } 
      } 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
    } 
} 
} 

そして:

public class HTTPSession implements Runnable { 

private Socket mSocket = null; 

public HTTPSession (Socket s) { 
    mSocket = s; 
} 


public void run() { 

    InputStream ips = null; 

    try { 
     mSocket.setSoTimeout(15000); 
     ips = mSocket.getInputStream(); 
     ips.read(); 
    } 
    catch (Exception e) { 
     e.printStackTrace(); 
     Log.v("HTTPSession", "Socket connected: " + mSocket.isConnected() + ", Socket closed: " + mSocket.isClosed() + ", InputShutdown: " + mSocket.isInputShutdown()); 
    } 
    finally { 
      try { ips.close(); } catch (IOException ioe) { } 
      try { mSocket.close(); } catch (IOException ioe) { } 
    } 

} 
} 

のでServerThreadが接続を受け付け、たHTTPSessionがソケットから読み取ろうとすると、時にはそれは15の後にしてSocketTimeoutExceptionをスローここで、可能な限りストリップダウン関連するコードは、です秒が上がっています。

この場合、キャッチログインステートメントの出力は次のようになります。 ソケット接続:trueの場合、ソケットが閉じ:偽、InputShutDownを:偽

を与えますか?確かに15秒で十分ですが、主流のウェブブラウザがデータを送信していない可能性は低いですが、なぜ私はそれを読むことができませんか?

私はこの問題の入力を感謝します。

答えて

1

SocketTimeoutExceptionは1つのことを意味します。タイムアウト期間内にデータが利用できませんでした。タイムアウト時間内にタイムアウトを送信しなかった場合、または少なくともタイムアウト時間内にサーバーのソケット受信バッファに到着しなかった場合は、タイムアウト時間が短すぎます。

私は15秒がサーバー側のタイムアウトに対して少し積極的だと言います。 30分から数分はもっと似ています。

+0

ありがとうございました!おそらく、完全なコードが実際にソケットをWiFi IPにバインドしていると言わざるを得ないので、比較的高帯域幅/低遅延の環境です。私は長いタイムアウトで遊んでみましたが、同じ数の例外が発生しています。短いタイムアウトのもう1つの理由は、15秒後にリクエストが成功する可能性が非常に低い場合、ユーザーが2分間空白の画面を見ていないようにすることです。 –

0

あなたが言ったように、ブラウザが何も送信していない限り、このコードが失敗する理由は何もありません。 ips.read();System.out.println(ips.read());に変更して、それを確認することができます。 stdoutにバイトが現れると、ブラウザは何かを送信しました。私の推測では、あなたの完全なコードで、あなたは要求の終わりを正しく認識せず、より多くのデータを待つことになります。 15秒後にタイムアウトします。しかし、それはちょうど推測です。問題を示すコードを投稿すると、誰かがあなたに決定的な答えを与えることができるかもしれません。

+0

あなたの提案をありがとう。これは間違いなく、例外がスローされたときに1バイトを読み取ることなく失敗した最初の読み取りです。私はこれがデバイス固有の問題だと思っています。私はちょうど今、別のデバイスで同じコードを実行し、10kを超えるリクエストでエラーを引き起こすことができませんでした。同じ-apkをMotorola Milestone XT720に置き、最初の50件のリクエストに対して5つの例外をスローします。 –

+0

私はあなたがそのようなことをどのようにチェックするか分かりません。アンドロイド用の[wireshark](http://www.wireshark.org/)のようなユーティリティはありますか? –

関連する問題