我有一些奇怪的套接字行为。我已经使用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()
读取整个消息,并且您需要完全重新考虑超时策略。