2010-10-18 143 views
3

我有一些奇怪的套接字行为正在进行。我使用setSoTimeout设置了5秒的超时时间。在我的情况下,这应该是充足的时间。根据在线Java文档,如果超时,应该抛出一个SocketTimeoutException。它还表示套接字仍然有效。所以我想抓住它然后继续。然而,而不是内部捕获,外部捕获IOException捕捉的说法,当我输出到日志的细节,它说这是一个SocketTimeoutException。另一个令人困惑的事情是,我将超时从5秒改为15秒,并记录每次读取所花费的时间,时间总是在毫秒范围内,甚至从未接近1秒。任何想法都非常感谢。Android - 套接字超时

ReadThread代码片段

@Override 
public void run() 
{ 
    try 
    { 
     while (true) 
     { 
      byte[] sizeBuffer = new byte[BYTES_FOR_MESSAGE_SIZE]; 

      int bytesRead = this.inputStream.read(sizeBuffer); 

      int length = 0; 

      for (int i = 0; i < BYTES_FOR_MESSAGE_SIZE; i++) 
      { 
       int bitsToShift = 8 * i; 
       int current = ((sizeBuffer[i] & 0xff) << bitsToShift); 
       length = length | current; 
      } 

      byte[] messageBuffer = new byte[length]; 


      this.socket.setSoTimeout(5000); //5 second timeout 

      try 
      { 
       this.inputStream.read(messageBuffer); 
      } 
      catch(java.net.SocketTimeoutException ste) 
      { 
       Log.e(this.toString(), "---- SocketTimeoutException caught ----"); 
       Log.e(this.toString(), ste.toString()); 
      } 

     } 
    } 
    catch (IOException ioe) 
    { 
     Log.e(this.toString(), "IOException caught in ReadThread"); 
     Log.e(this.toString(), ioe.toString()); 
     ioe.printStackTrace(); 
    } 
    catch (Exception e) 
    { 
     Log.e(this.toString(), "Exception caught in ReadThread"); 
     Log.e(this.toString(), e.toString()); 
     e.printStackTrace(); 
    } 

    this.interfaceSocket.socketClosed(); 

}// end run 

回答

1

唯一的例外可能是夹在第一次尝试捕获因为this.inputStream.read较早调用的()。你有两个这样的电话:一个在外面尝试,一个在内部尝试。

您是否验证数据是否正在读取?如果正在读取数据,那么您应该期望读取操作在几毫秒后返回。如果数据没有被读取,那么读取操作应该在指定的时间内在那里阻塞。也许这与你设置SoTimeout的顺序有关(也许这样做可能会有所帮助)。

祝你好运, B-Rad公司

2

我与布莱恩同意。您可能在第一次阅读时获得暂停,而不是第二次。一次设置的超时将保持有效,直到您再次更改为止。如果你阅读'消息',你的第二次阅读呼叫似乎假定(a)它将读取整个消息,并且(b)如果整个消息在5秒内没有到达,它将超时。它不这样工作。它会超时如果没有什么到达5秒内,或其他它将读取任何已到达,直到message.length。但它只能是一个字节。

您应该使用DataInputStream.readFully()来读取整个消息,并且您需要完全重新考虑您的超时策略。