Java-TCP异常

Java-TCP异常,java,sockets,tcp,Java,Sockets,Tcp,我有一个TCP服务器和客户端,都是用Java编写的,在RHEL5.3和jdk1.6上的不同机器上运行。我已经处理了几乎所有我能找到的检测“服务器”上断开连接的方法 下面是服务器代码的一个片段 private void listenforConnection() { try { socket = serverSocket.accept(); socket.setTcpNoDelay(true); socket.setKeepAlive(tr

我有一个TCP服务器和客户端,都是用Java编写的,在RHEL5.3和jdk1.6上的不同机器上运行。我已经处理了几乎所有我能找到的检测“服务器”上断开连接的方法

下面是服务器代码的一个片段

private void listenforConnection() {
    try {

        socket = serverSocket.accept();
        socket.setTcpNoDelay(true);
        socket.setKeepAlive(true);
        socket.setSoTimeout(5);

        bosTcpOutStream = new BufferedOutputStream(socket.getOutputStream());
        bisTcpInStream = new BufferedInputStream(socket.getInputStream());
        log("New connection accepted from " + socket.getRemoteSocketAddress().toString());
        sendHeartBeatsToClient();

    } catch (IOException ie) {
        log("Listener IOException : " + ie.getMessage());
    }
}           

private void sendHeartBeatsToClient() {
    try {
        while (true) {
            long lngCurrentMillis=System.currentTimeMillis() ;
            if ((lngCurrentMillis - lngLastSentMessageTime) >= 5000) {
                byte[] bHeartBeat = getHeartBeatMessage();
                bosTcpOutStream.write(bHeartBeat);
                bosTcpOutStream.flush();
                lngLastSentMessageTime = System.currentTimeMillis();
                log("Heartbeat sent.");
            } else {
                try {
                    if (bisTcpInStream.read() == -1) {
                        log("Read Input Stream returned -1");
                        break;
                    }
                } catch (SocketTimeoutException se) {
                    //Do nothing as i am not expecting the client to send anything.
                } catch (IOException e) {
                    log("Read Input Stream error - " + e.getMessage());
                    break;
                }
            }
            Thread.sleep(1);
        }
    } catch (IOException e) {
        disconnectClientAndCloseSocket();
        log("IO Exception" +e.getMessage());
    } catch (InterruptedException e) {
        disconnectClientAndCloseSocket();
        log("Thread interrupted terminating." + e.getMessage());
    }
}
我还修改了“服务器”机器上的tcp keepalive内核参数,如下所示:

net.ipv4.tcp_keepalive_time=2
net.ipv4.tcp_keepalive_probes=1
net.ipv4.tcp_keepalive_intvl=2
现在,当我通过拔下客户端计算机的网络电缆(在它建立连接并从服务器接收初始数据后)模拟断开连接时,我看到了两种我无法理解的不同结果:-

  • 如果在成功连接客户端10到15秒后拔下电缆。在拔下电缆的10分钟后,我在“服务器”上收到一个IO异常,显示“无主机路由”

  • 如果在成功连接客户端60秒左右后拔下电缆。在“服务器”上,在10秒内引发IO异常,并显示“连接超时”。记住“保持活动”设置,这是有效的行为

  • 我已经试过几次了,结果总是一样的


    我不明白的是为什么第一个结果需要10分钟,而第二个结果却不一样。我遗漏了什么吗?

    在这10分钟内,你有没有收到任何日志消息?我不明白你的问题,你是在问例外情况吗?我说的是
    log(“心跳发送”)在10分钟内。你不需要保持活动状态、心跳和读取超时,5ms是读取超时的可笑短时间。为什么说5ms是读取超时的短时间?