10

我正在开发一个通过 TCP/IP 托管 3rd 方设备的服务器,并且遇到了突然的连接中断(设备通过蜂窝连接)。我需要找到一种方法来检测断开连接,而不必将数据写入设备本身。

我已经研究过使用 TCP keepalive 功能,但 Java 似乎不允许对 keepalive 操作的时间进行任何调整。

有没有建议的方法来做到这一点?

我的简化套接字代码如下:

public class Test2Socket {
    public static void main(String[] args) {
        try {
            ServerSocket skt = new ServerSocket(1111);

            Socket clientSocket = skt.accept();

            clientSocket.setKeepAlive(true);

            System.out.println("Connected..");

            BufferedReader input = new BufferedReader(new InputStreamReader(clientSocket.getInputStream()));

            String inputLine;

            while((inputLine = input.readLine()) != null)
            {
                System.out.println(inputLine);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

任何反馈将不胜感激。

4

5 回答 5

8

TCP 堆栈的内置保持活动不会让您走得太远。这是因为您的应用程序无法调整保活间隔,它是由操作系统设置的,并且默认值相当高(小时)。这不是 Java 特有的。

如果您需要在合理的时间内超时,则必须在要使用的协议中实现某种保持活动状态。我见过的大多数高级协议都具有某种 NOP 功能,您可以在其中发送“你在吗?”。消息并且对方发送“是的,我在这里”回复,而没有做任何其他事情。

于 2013-11-05T10:36:21.670 回答
4

有关 TCP Keep-Alives 的深入讨论,请参见我的回答

但基本上 TCP Keep-Alives 可能是检测陈旧连接的最佳方法。主要问题是操作系统默认设置为在连接被检查前 2 小时,在连接实际被丢弃之前还有 11 分钟的 Keep-Alive 数据包。

当 TCP 已经内置时,不要编写自己的应用层 Keep Alive 协议。您所要做的就是将 TCP 超时设置为更合理的值,例如 2-3 分钟。

不幸的是,由于 TCP 超时是在操作系统级别而不是在 JVM 中管理的,因此很难(但并非不可能)在代码中基于每个套接字配置 TCP 超时。

于 2015-11-25T23:19:19.227 回答
0

将读取超时设置setSoTimeout(),为合理的值,例如将预期响应时间加倍,然后捕获结果SocketTimeoutException.

注意没有“Java TCP KeepAlive”这样的东西。

于 2013-11-05T22:00:12.837 回答
0

当您在套接字上调用 setKeepalive() 时,将使用系统参数(可调)。(在 Debian 8 下使用 openjdk7 进行了检查。)

因为我需要完全相同的功能,所以我编写了一个名为libdontdie的小型库,它可以预加载并与 Java 一起使用。

于 2015-03-04T00:12:31.987 回答
0

这个图书馆的作者在这里:-)

如前所述,除非您依赖直接在 TCP 协议中实现的难以配置的功能(保持活动状态),否则如果不通过连接实际发送数据,您几乎无法检测到故障。

引用的库封装了传统的 Java 套接字,同时添加了易于配置的定期连接检查和 ACK。(这些对应用程序程序员来说是不可见的)。一旦检测到故障,将通知所有登记的观察者。(取决于您的配置,可以接近实时)。

好处是该库相当容易使用(至少在我自己的项目中工作相当可靠)。

不利的一面是,应用层并不打算用于连接检查。所以基本上那个lib正在以他们可能不打算使用的方式使用东西。

旁注:您提到您的客户是蜂窝网络。虽然链接库可以在 android 上运行,但您可能会查看推送通知服务,而不是自己处理连接问题。这可以改善例如电池消耗。

于 2016-08-01T17:48:08.287 回答