java Android - 套接字超时
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3962706/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Android - Socket time out
提问by bursk
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 valid. 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.
我有一些奇怪的套接字行为。我使用 setSoTimeout 设置了 5 秒的超时。在我的情况下,这应该是足够的时间。根据在线 java 文档 aSocketTimeoutException
如果超时应该抛出。它还说套接字仍然有效。所以我想抓住它然后继续。但是,外部捕获不是内部捕获,而是IOException
捕获异常,当我将详细信息输出到日志时,它说它是一个SocketTimeoutException
. 另一个令人困惑的事情是我将超时从 5 秒更改为 15 秒并记录每次读取所需的时间,时间始终在毫秒范围内,甚至从未接近一秒。任何想法都非常感谢。
ReadThread
code snippet
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
回答by user207421
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 nothingarrives within 5s, or elseit will read whatever has arrived, up to message.length. But it could only be one byte.
您阅读“消息”的第二次读取呼叫似乎假设 (a) 它将读取整个消息,并且 (b) 如果整个消息未在 5 秒内到达,它将超时。它不是那样工作的。如果在 5 秒内没有任何内容到达,它将超时,否则它将读取已到达的任何内容,直至 message.length。但它只能是一个字节。
You should use DataInputStream.readFully()
to read the entire message, and you need to completely reconsider your timeout strategy.
您应该使用DataInputStream.readFully()
阅读整个消息,并且您需要完全重新考虑您的超时策略。
回答by Brian
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.
由于较早调用 this.inputStream.read(),异常可能在第一次 try catch 中被捕获。您有两个这样的调用:一个在外部尝试中,一个在内部尝试中。
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).
您是否已验证是否正在读取数据?如果正在读取数据,那么您应该期望读取操作在几毫秒后返回。如果未读取数据,则读取操作应在您指定的时间内阻塞在那里。也许这与您 setSoTimeout 的顺序有关(也许早点这样做会有所帮助)。
Good luck, B-Rad
祝你好运,B-Rad