我有一个问题,
我的客户端需要从服务器监听特定的时间,如果它在那段时间内没有收到服务器的回复,则必须关闭连接。
我在客户端有两个线程,在时间到期后将布尔变量更新为false,以及从服务器和计时器检查msg的其他线程。
我的代码是这样的:
while(true){
if(l=is.readLine().equals(msg))
{
// do processing
break;
}
if(timer)
break;
}
所以我的while循环continuoslu检查msg和计时器。 问题是is.readline()阻塞了调用,并且从服务器上无休止地等待msg。
我该怎么做呢。
我试过
if(l=is.readLine()!=null and l.equals(msg))
但没有工作。
答案 0 :(得分:1)
你可以检查这两个条件,但这比使用一个轮询你的连接并关闭那些已经超时的线程更加复杂。
即。有一个每隔一秒左右唤醒的线程,并调用连接列表中每个连接的checkTimeout()方法。如果checkTimeout检测到超时已达到,则设置closed = true;
易失性标志并关闭()s连接。如果抛出异常,如果在连接关闭后发生异常,我会忽略它。
您可以使用SocketTimeout,但这似乎并不总是在所有平台上按预期工作。见Socket.setSoTimeout(timeinSECONDS);
答案 1 :(得分:0)
为服务器侦听器创建新线程。如果新线程已从服务器接收输入,则让其设置内部切换。
在主线程中,启动一个循环,等待连接超时或服务器线程连接。如果它连接,则处理服务器的输入。如果没有,并且超时,则终止线程(并可能关闭连接)。
答案 2 :(得分:0)
在特定情况下,我认为Polling是@Peter所说的最佳选择。 但是也可以使用2个线程来完成它:
NetworkThread implements Runnable, Closeable{
BufferedReader r;
volatile boolean readyToClose = false;
@Override
public void run(){
//initialize r as t = new BufferedReader(new InputStreamReader(socket.getInputStream()))
String s = null;
while((s= r.readLine())!=null){
readyToClose = true;
//do whatever
}
}
public void close() throws IOException
{
if(readyToClose()
r.close();
}
}
让另一个线程在此期间被阻止(sleep
)。然后拨打NetworkThread#close()
。这将关闭流,另一个线程将退出循环。
答案 3 :(得分:0)
谢谢大家......
我找到了解决这个问题的简单方法......
我在调用readline之前检查缓冲区中是否有数据
if(ir.ready())
ir.readLine()
只有在非阻塞的情况下,abouve才会调用readLine。
答案 4 :(得分:-1)
您可以使用CountdownLatch来实现此目的。启动网络线程,然后在倒计时锁存器上调用await:
CountDownLatch latch = new CountDownLatch(1);
// start network thread
networkThread.start();
boolean wasFinished = latch.await(you_timeout);
// Interrupt network thread as it still waiting:
if(!wasFinished) {
networkThread.interrupt();
}
在读取成功后的网络线程中调用latch.countDown();