0

我有一个问题,

我的客户端需要在特定时间内从服务器监听,如果在这段时间内没有收到服务器的回复,它必须关闭连接。

我在客户端有两个线程,一个在时间到期后将布尔变量更新为 false,另一个线程检查来自服务器的 msg 以及计时器。

我的代码是这样的:

while(true){
    if(l=is.readLine().equals(msg))
    {
        // do processing
        break;
    }
    if(timer)
        break;
}

所以我的while循环不断检查味精和计时器。问题是 is.readline() 正在阻止呼叫,并且无限期地等待来自服务器的消息。

我该怎么做?

我试过了

if(l=is.readLine()!=null and l.equals(msg)) 

但没有用。

4

5 回答 5

1

您可以检查这两个条件,但这比拥有一个轮询您的连接并关闭已超时连接的线程要复杂得多。

即有一个线程每隔一秒左右唤醒一次,并调用连接列表中每个连接的 checkTimeout() 方法。如果 checkTimeout 检测到已达到超时,它会设置一个closed = true;volatile 标志并关闭()连接。如果抛出异常,如果在连接关闭后发生,我将忽略它。

您可以使用 SocketTimeout,但这并不总是在所有平台上都按预期工作。见Socket.setSoTimeout(timeinSECONDS);

于 2013-04-25T07:49:08.983 回答
0

为服务器侦听器创建一个新线程。如果新线程已接收到来自服务器的输入,则让新线程设置内部切换。

在您的主线程中,启动一个循环,等待连接超时或服务器线程连接。如果它连接,则处理服务器的输入。如果没有,并且超时,则终止线程(并可能关闭连接)。

于 2013-04-25T07:36:52.980 回答
0

在给定的情况下,我认为投票是@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()。这将关闭流,另一个线程将退出循环。

于 2013-04-25T08:02:33.357 回答
0

谢谢大家...

我找到了解决这个问题的简单方法......

我在调用 readline 之前检查缓冲区中是否有数据

if(ir.ready())
    ir.readLine()

仅当它是非阻塞的时,上面才会调用 readLine。

于 2013-04-26T07:47:21.517 回答
-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();

于 2013-04-25T07:42:16.490 回答