java - Android - 套接字超时

标签 java android sockets

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

ReadThread 代码 fragment

@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

最佳答案

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

您在读取“消息”时的第二次读取调用似乎假设 (a) 它将读取整条消息,并且 (b) 如果整条消息未在 5 秒内到达,它将超时。它不是那样工作的。如果在 5 秒内没有到达,它将超时,否则它将读取到达的任何内容,直到 message.length。但它只能是一个字节。

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

关于java - Android - 套接字超时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3962706/

相关文章:

android - 如何覆盖主页按钮的功能?

android - 使用 Appcelerator Titanium 开发移动应用程序

python - 如何不重复发送数据?

java - 在 Java 单元测试中,如何断言数字在给定范围内?

java - 谷歌应用引擎 HardDeadlineExceededError

android - EditText 在 Lollipop 下方以一种奇怪的方式显示

c - 从socket读取到buffer,再从buffer逐行读取实现http语言

java - 传递参数从mysql java检索数据的方法

java - 通过单独的方法结束游戏

c++ - 如何获取 socket 上是否有任何可用数据可在 boost::asio 中读取?