Определите сеть на сокете tcp, используя TCP_KEEPALIVE в C

Я пишу клиентскую программу 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 минут или около того). Пожалуйста, предложите любое другое решение.

Платформа: Visual C 2012 на Windows 7 Профессиональная

2 ответа

Глобальное определение:

struct tcp_keepalive alive;
DWORD dwBytesRet = 0;

Поддержание реализации начинается отсюда:

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");
}

В Windows 2000 и более поздних версиях вы можете использовать WSAIoctl(SIO_KEEPALIVE_VALS) вместо setsockopt(SO_KEEPALIVE) установить пользовательские значения времени ожидания / интервала поддержки активности для каждого сокета.

Вы также можете использовать select(), WSAAsyncSelect(), или же WSAEventSelect() определить, когда данные доступны для чтения, прежде чем читать их. Если тайм-аут наступает до поступления данных, просто закройте сокет.

Другие вопросы по тегам