找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 10480|回复: 14

ACE中keepalive的疑问

  [复制链接]
发表于 2012-5-3 14:24:18 | 显示全部楼层 |阅读模式
本帖最后由 qq496683952 于 2012-5-3 14:26 编辑

从论坛了解到心跳检测有2种方式:
1.直接使用keepalive
2.自己在应用层发心跳包.

自己根据实际情况首先尝试第一种方式
具体代码是从网上找的:
int Opt = 1;
tcp_keepalive live,liveout;
  live.keepaliveinterval=5000;
  live.keepalivetime=10000;
  live.onoff=TRUE;
  int iRet = stream.set_option(SOL_SOCKET,SO_KEEPALIVE,&Opt,sizeof (int));
  if(iRet == 0)
{
     DWORD dw;
         if(WSAIoctl((SOCKET)h,SIO_KEEPALIVE_VALS,&live,sizeof (live),&liveout,sizeof(liveout),&dw,NULL,NULL)== SOCKET_ERROR)
        {
                //Delete Client
                 return;
         }
}

但是看了之后有如下疑问:
1.调用set_option设置SO_KEEPALIVE之后,检测到对方断开,ACE会调用handle_close还是需要自己添加处理?
2.如果自己添加处理要如何做?

谢谢了.


发表于 2012-5-3 14:55:02 | 显示全部楼层
印象中(有点不确定),这样做没用。这个keepalive是全局性的变量,需要改注册表。
所以它不是应用程序的最佳选择。还是自己做心跳包吧。TCP不做断开通知功能,是故意这么设计的,而并非缺陷,具体可以参考UNIX网络编程。
 楼主| 发表于 2012-5-3 16:03:28 | 显示全部楼层
winston 发表于 2012-5-3 14:55
印象中(有点不确定),这样做没用。这个keepalive是全局性的变量,需要改注册表。
所以它不是应用程序的最 ...

哦,行.
自己去做心跳包算了
有没有推荐的心跳包方式?
效率和可靠性高点的
:P
谢谢
发表于 2012-5-3 16:38:02 | 显示全部楼层
最简单的: 长度 + 命令  , 几个字节而已
1 .收到该心跳包后,为该连接打时间戳。
2 .启个定时器定时检查上次收报时间和当前时间的差值,看看是否大于你的设定值,如果大于,断开该连接
发表于 2012-5-3 16:47:57 | 显示全部楼层
应该不要自己写处理,这样做应该就可以了。
 楼主| 发表于 2012-5-3 17:01:45 | 显示全部楼层
wesom 发表于 2012-5-3 16:38
最简单的: 长度 + 命令  , 几个字节而已
1 .收到该心跳包后,为该连接打时间戳。
2 .启个定时器定时检查 ...

既然收到了心跳包,为什么还要断开?
 楼主| 发表于 2012-5-3 17:02:34 | 显示全部楼层
sevencat 发表于 2012-5-3 16:47
应该不要自己写处理,这样做应该就可以了。

那异常断开的时候,自己没办法加入自己的处理啊,比如释放内存之类的?
发表于 2012-5-3 17:04:17 | 显示全部楼层
翻了翻资料,应该可以。

SO_KEEPALIVE
optval Type
Get/Set
Winsock Version
Description

BOOL
Both
1+
If TRUE, socket is configured to send keepalive messages on the session.


For a TCP-based socket, an application can request that the underlying service provider enable the use of keepalive packets on TCP connections by turning on the SO_KEEPALIVE socket option. On Windows platforms, keep-alives are implemented in accordance with section 4.2.3.6 of RFC 1122. If a connection is dropped as the result of keepalives, the error code WSAENETRESET is returned to any calls in progress on the socket, and any subsequent calls will fail with WSAENOTCONN. For the exact implementation details, consult the RFC. The important point is that keepalives are sent at intervals no less than two hours apart. The two-hour keepalive time is configurable via the Registry; however, changing the default value changes the keepalive behavior for all TCP connections on the system, which is generally discouraged. Another solution is to implement your own keepalive strategy. Sockets of type SOCK_DGRAM do not support this option.

The Registry keys for keepalives are KeepAliveInterval and KeepAliveTime. Both keys store values of type REG_DWORD in milliseconds. The former key is the interval separating keepalive retransmissions until a response is received; the latter entry controls how often TCP sends a keepalive packet in an attempt to verify that an ideal connection is still valid. In Windows 95, Windows 98, and Windows Me, these keys are located under the following Registry path:

\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP
In Windows NT, store the keys under

\HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\TCPIP\Parameters
In Windows 2000, a new socket ioctl command—SIO_KEEPALIVE_VALS —allows you to change the keepalive value and interval on a per-socket basis, as opposed to a system-wide basis. This ioctl command is described later in this chapter.


SIO_KEEPALIVE_VALS
Which Function?
Input
Output
Winsock Version
Description

WSAIoctl
tcp_keepalive
tcp_keepalive
2+
Sets the TCP keepalive active on a per-connection basis


This ioctl command allows setting the TCP keepalive active on a per-connection basis and allows you to specify the keepalive interval. The socket option SO_KEEPALIVE also enables TCP keepalives, but the interval on which they are sent is set in the Registry. Changing the Registry value will change the keepalive interval for all processes on the machine. This ioctl command allows you to set the interval on a per-socket basis. To set the keepalive active on the given connected socket, initialize a tcp_keepalive structure and pass it as the input buffer. The structure is defined as

struct tcp_keepalive
{
    u_long    onoff;
    u_long    keepalivetime;
    u_long    keepaliveinterval;
}
The meaning of the structure fields keepalivetime and keepaliveinterval are identical to the Registry values discussed in the SO_KEEPALIVE option presented earlier in this chapter. Once a keepalive is set, you can query for the current keepalive values by calling WSAIoctl with the SIO_KEEPALIVE_VALS ioctl command and supplying a tcp_keepalive structure as the output buffer. This ioctl command is available on Windows 2000 and later versions.
 楼主| 发表于 2012-5-3 17:25:18 | 显示全部楼层
winston 发表于 2012-5-3 17:04
翻了翻资料,应该可以。

SO_KEEPALIVE

谢谢了!!
 楼主| 发表于 2012-5-3 17:25:49 | 显示全部楼层
不知道linux和win有多少区别?
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-1 22:40 , Processed in 0.024747 second(s), 5 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表