java setkeepalive_如何在Android中设置Keepalive超时?

我想可能是相当重要能够设置存活上超时每个应用水平,尤其是在移动设备上,因为它可能是坏的网络条件(WIFI /手机)下。如果应用程序未发送(m)任何数据但使用持久连接,则套接字将不会检测连接是否丢失,除非它发送tcp keepalive探针。通常可以通过setsockopt(2)调用设置此选项,但android sdk仅提供setKeepAlive(boolean)选项。在堆栈较深处,该函数调用libcore.io.ForwardingOs.setsockoptInt(...),这是不可用直接,也不是所需的文件描述符。 通过使用java反射,无论如何设置保持活动超时是可能的,例如,摹这样的:

private final static int SOL_TCP = 6;

private final static int TCP_KEEPIDLE = 4;

private final static int TCP_KEEPINTVL = 5;

private final static int TCP_KEEPCNT = 6;

protected void setKeepaliveSocketOptions(Socket socket, int idleTimeout, int interval, int count) {

try {

socket.setKeepAlive(true);

try {

Field socketImplField = Class.forName("java.net.Socket").getDeclaredField("impl");

socketImplField.setAccessible(true);

if(socketImplField != null) {

Object plainSocketImpl = socketImplField.get(socket);

Field fileDescriptorField = Class.forName("java.net.SocketImpl").getDeclaredField("fd");

if(fileDescriptorField != null) {

fileDescriptorField.setAccessible(true);

FileDescriptor fileDescriptor = (FileDescriptor)fileDescriptorField.get(plainSocketImpl);

Class libCoreClass = Class.forName("libcore.io.Libcore");

Field osField = libCoreClass.getDeclaredField("os");

osField.setAccessible(true);

Object libcoreOs = osField.get(libCoreClass);

Method setSocketOptsMethod = Class.forName("libcore.io.ForwardingOs").getDeclaredMethod("setsockoptInt", FileDescriptor.class, int.class, int.class, int.class);

if(setSocketOptsMethod != null) {

setSocketOptsMethod.invoke(libcoreOs, fileDescriptor, SOL_TCP, TCP_KEEPIDLE, idleTimeout);

setSocketOptsMethod.invoke(libcoreOs, fileDescriptor, SOL_TCP, TCP_KEEPINTVL, interval);

setSocketOptsMethod.invoke(libcoreOs, fileDescriptor, SOL_TCP, TCP_KEEPCNT, count);

}

}

}

}

catch (Exception reflectionException) {}

} catch (SocketException e) {}

}

这工作至少直到以下要求满足:

libcore.io.ForwardingOs.setsockoptInt/4存在于当前的SDK版本

java.net.Socket有impl成员在当前sdk版本

java.net.Socket->impl是java.net.SocketImpl实例在当前的SDK版本

java.net.SocketImpl已在当前SDK版本一个fd构件

TCP_KEEPIDLE,TCP_KEEPINTVL和TCP_KEEPCNT具有在当前SDK版本相同的值 (4,5和6)和所有的Android设备/体系结构。

参见luni/src/main/java/libcore/io/Os.java,luni/src/main/java/java/net/Socket.java和luni/src/main/java/java/net/SocketImpl.java来自platform/libcore存储库。 TCP_KEEPIDLE,TCP_KEEPINTVL和TCP_KEEPCNT自从2.2.3 r2以及所有体系结构似乎都具有相同的Android版本值。这可以被验证,例如通过在android platform/ndk存储库中执行find . -name tcp.h | xargs grep -ho "TCP_KEEP\w\+\s\+\d\+" | sort | uniq -c。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值