Android - 套接字超时

时间:2010-10-18 19:38:51

标签: java android sockets

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

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

2 个答案:

答案 0 :(得分:2)

我同意布莱恩的观点。您可能在第一次读取时获得超时,而不是第二次读取。设置的超时一直有效,直到您再次更改为止。

您在第二次阅读中读取“消息”似乎假定(a)它将读取整个消息,(b)如果整个消息未在5s内到达,它将超时。它不像那样工作。如果 nothing 在5秒内到达,它将会超时,它将读取已到达的任何内容,直至message.length。但它只能是一个字节。

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

答案 1 :(得分:1)

由于之前调用this.inputStream.read(),可能会在第一次尝试catch中捕获该异常。你有两个这样的调用:一个在外部尝试,一个在内部尝试。

您是否验证过是否正在读取数据?如果正在读取数据,那么您应该期望读取操作在几毫秒后返回。如果未读取数据,则读取操作应在指定的时间内阻止。也许这与你setSoTimeout的顺序有关(也许早点做它会有帮助)。

祝你好运, B-Rad公司