Определите сеть на сокете 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()
определить, когда данные доступны для чтения, прежде чем читать их. Если тайм-аут наступает до поступления данных, просто закройте сокет.