1

我正在编写一个从 tcp 服务器接收数据的 tcp 客户端程序。当网络变坏(即网络中断)时,我无法关闭连接。

我使用 SO_KEEPALIVE 允许应用程序为套接字连接启用保持活动数据包。SO_KEEPALIVE 属性打开成功,但我无法修改 KeepAliveTime 的默认值(即 2 小时)

编辑 KeepAliveTime 的另一个可用选项是编辑注册表值,但我在HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters位置找不到注册表项

以下代码检查并启用 SO_KEEPALIVE。

char optval;
char optout;
int optlen;
int optlen2;
optlen = sizeof(optval);
optlen2 = sizeof(optout);
got = getsockopt(loFds[i], SOL_SOCKET, SO_KEEPALIVE, &optval, &optlen );
if(got < 0) 
{
    printf("getsockopt unsuccessful. Error %ld\n", WSAGetLastError());
}
else if (got == 0)  {
//printf("SO_KEEPALIVE is %s\n", (optval ? "ON" : "OFF"));
printf("SO_KEEPALIVE is %ld\n", optval);
}


optval = 1;
//optout = 1;
got = (setsockopt(loFds[i], SOL_SOCKET, SO_KEEPALIVE, &optval, optlen));
 if( got < 0) 
 {
    printf("setsockopt unsuccessful on socket\n");
 }
 else if (got == 0)  {
     printf("SO_KEEPALIVE set on socket\n");
 }



got = (getsockopt(loFds[i], SOL_SOCKET, SO_KEEPALIVE, &optout, &optlen2 ));
if( got < 0) 
{

    printf("getsockopt unsuccessful. Error %ld\n", WSAGetLastError());

}
else if (got == 0)  {
    printf("SO_KEEPALIVE is %ld\n", optval);
}

但我要求它在用户定义的时间(可能是 5 分钟左右)后断开套接字。请提出任何其他解决方案。

平台:Windows 7 Professional 上的 Visual C 2012

4

2 回答 2

0

全局定义:

struct tcp_keepalive alive;
DWORD dwBytesRet = 0;

Keep alive 实现从这里开始:

alive.onoff = TRUE;             //keepalive enabled
alive.keepaliveinterval = 1000; //Interval between keepalive probes is set to 1 sec

alive.keepalivetime = 20000;    //Keep alive time set to 20 sec

if (WSAIoctl(loFds[i], SIO_KEEPALIVE_VALS, &alive, sizeof(alive), NULL, 0,
&dwBytesRet, NULL, NULL) == SOCKET_ERROR)
{
    printf("WSAIotcl(SIO_KEEPALIVE_VALS) failed.\n");
}
else
{
    printf("WSAIotcl(SIO_KEEPALIVE_VALS) Success.\n");
}
于 2014-07-20T13:13:55.700 回答
0

在 Windows 2000 和更高版本上,您可以使用WSAIoctl(SIO_KEEPALIVE_VALS)而不是setsockopt(SO_KEEPALIVE)基于每个套接字设置自定义保持活动超时/间隔值。

您还可以在读取数据之前使用select()WSAAsyncSelect()WSAEventSelect()来检测数据何时可供读取。如果在数据到达之前发生超时,只需关闭套接字。

于 2014-07-19T19:38:41.280 回答