没有额外的readLine()循环无法检测断开连接

时间:2014-01-16 22:00:43

标签: java sockets loops timer while-loop

我正在开发一个使用套接字的程序,目前我的代码中有一个函数可以每秒检查来自客户端的心跳。

private void userLoop() { // checks for incoming data from client
    Timer t = new Timer();
    t.schedule(new TimerTask() {
        @Override
        public void run() {
            try {
                socketIn.read(); // check for heartbeat from client

                String userInput;
                while ((userInput = br.readLine()) != null) {
                }

            } catch (Exception e) {
                ControlPanel.model.removeElement(getUsername());
                ControlPanel.append(getUsername() + " has disconnected.");
            }
        }
    }, 1000);
}

当客户通过X按钮关闭游戏,关闭他们的计算机,注销,无论它是什么,我收到消息“'用户名'已断开连接”。这正是我想要的,但是,它只适用于代码中的while循环。 while循环基本上什么都不做,我不知道为什么它不能解决。

如果我删除了while循环并且使用我的客户端断开连接,那么就不会从服务器端打印出来。

String userInput;
while ((userInput = br.readLine()) != null) {
}

以上基本上是死代码,什么都不做,但没有它我的程序不会按照应有的方式工作..

为什么需要代码,如何删除代码并使程序正常运行?

4 个答案:

答案 0 :(得分:0)

在这种情况下,你的while循环实际上会停止你的程序,直到你不再收到输入字符串。这不是死代码;这只是你安装等待的方式。

否则,根据我对Timer class的理解,它只会等待一秒钟,这可能会超过您等待捕获的时间跨度。

答案 1 :(得分:0)

我通过使用

更改try块中的所有内容来修复我的问题
br.readLine();

答案 2 :(得分:0)

有一种说法我听说过异常处理:“异常只应用于特殊情况。”客户端与服务器断开连接也不例外。

现在我已经把它放在胸前了,让我们继续吧。根据这个问题, socket.getInputSteam.read() does not throw when I close the socket from the client 听起来如果你在客户端正确地关闭了东西,读取调用就不会抛出。

答案 3 :(得分:0)

问题是当远程套接字关闭时,read()不会抛出异常,它只返回-1以表示流的结束。

以下情况应该无需致电readLine()

    try {
        int ret = socketIn.read(); // check for heartbeat from client
        if (ret == -1) {
            // Remote side closed gracefully
            clientDisconnected();
        }
    } catch (SocketTimeoutException e) {
        // Timeout -- handle as required
        handleTimeout();
    } catch (IOException e) {
        // Connection lost due to I/O error
        clientDisconnected()
    }