我有一些奇怪的套接字行为。我已经使用setSoTimeout将超时设置为5秒。在我的情况下,这应该有很多时间。根据在线Java文档,如果超时,应抛出SocketTimeoutException。它还说该套接字仍然有效。所以我想抓住它,然后继续。但是,除了内部捕获之外,外部捕获IOException捕获了expcept,当我将详细信息输出到日志时,它说这是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

最佳答案

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

您在其中读取“消息”的第二次读取呼叫似乎假设(a)它会读取整个消息,并且(b)如果整个消息未在5秒钟内到达,它将超时。它不是那样工作的。如果5秒钟之内什么都没有到达,它将超时,否则它将读取到达的所有内容,直到message.length。但是只能是一个字节。

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

08-04 05:23