I have some strange socket behavior going on. I've set an timeout of 5 seconds using setSoTimeout. This should be plenty of time in my situation. According to online java documentation a SocketTimeoutException
should be thrown if it times out. It also says that the socket is still val开发者_JAVA百科id. So I want to catch it and then continue. However instead of the inner catch, the outer catch IOException
is catching the expception and when I output to the log the details it says it was a SocketTimeoutException
. Another perplexing thing is I change the timeout from 5 seconds to say, 15 seconds and log the amount of time it take for every read, the times are always in the milli-second range, never even close to a second. Any ideas are GREATLY appreciated.
ReadThread
code snippet
@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
I agree with Brian. You are probably getting the timeout on the first read, not the second. The timeout once set remains in effect until you change it again.
Your second read call where you read the 'message' seems to assume (a) that it will read the entire message and (b) that it will timeout if the entire message doesn't arrive within 5s. It doesn't work like that. It will timeout if nothing arrives within 5s, or else it will read whatever has arrived, up to message.length. But it could only be one byte.
You should use DataInputStream.readFully()
to read the entire message, and you need to completely reconsider your timeout strategy.
The exception is probably caught in the first try catch because of the earlier call to this.inputStream.read(). You have two of these calls: one in the outer try, one in the inner try.
Have you validated if data is being read? If data is being read then you should expect the read operation to return after a few milliseconds. If data is not being read, then the read operation should block there for the time you specify. Maybe this has to do with the order by which you setSoTimeout (perhaps doing it earlier will help).
Good luck, B-Rad
精彩评论