Android - 套接字超时

3
我遇到了一些奇怪的socket行为。我使用了setSoTimeout设置了5秒的超时时间,这在我的情况下应该足够了。根据在线Java文档,如果超时了应该抛出SocketTimeoutException,并且它说socket仍然有效。所以我想要捕获它,然后继续执行。然而,不是内部catch语句,而是外部的IOException catch语句捕获了异常,并且当我输出日志详细信息时,它说是一个SocketTimeoutException。另一个令人困惑的事情是,我将超时时间从5秒更改为15秒,并记录每次读取所需的时间,时间总是在毫秒范围内,甚至没有接近1秒。非常感谢您的任何想法。
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个回答

2

我同意Brian的观点。你可能是在第一次读取时超时了,而不是第二次。一旦设置了超时时间,它将保持有效,直到你再次更改。

你第二个读取调用,其中读取“message”的做法似乎假设(a)它将读取整个消息,并且(b)如果整个消息在5秒内没有到达,则会超时。但事实并非如此。如果在5秒钟内没有任何消息到达,它将超时,或者否则,它将读取已经到达的所有内容,最多为message.length。但这可能只有一个字节。

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


1

可能在第一个try-catch中捕获了异常,这是因为之前调用了this.inputStream.read()函数。你有两个这样的调用:一个在外部try中,另一个在内部try中。

你是否验证了数据是否被读取?如果数据正在被读取,则应该在几毫秒后返回读取操作。如果没有读取数据,则读取操作应该一直阻塞在那里,直到你指定的时间。也许这与你设置setSoTimeout的顺序有关(也许先设置会有帮助)。

祝好运, B-Rad


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接