Модераторы: feodorv
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> подскажите с getsockname, как определить активность сокета 
:(
    Опции темы
hawk3500
Дата 8.2.2011, 20:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 246
Регистрация: 6.2.2009

Репутация: нет
Всего: 2



Здравствуйте.
Пишу клиент сервер.
На каждого клиента после accept организуется свой поток приёма.
И вот стала задача, как определить активен сокет на стороне клиента или нет.
При этом крайн не желательно использовать для такого определения recv т.к. структура пакетов строго
регламентированна и не подлежит изменениям.

Псмотрел на этом форуме.
Нашёл вариант:
Код

  AnsiString MySocket::GetClientIP(void)const
{
  int addrLen = sizeof(sockaddr);
  struct sockaddr_in CliAddr;
  getsockname
             (
             S,
             (LPSOCKADDR)&CliAddr,
             &addrLen
             );
  AnsiString CliIP = (AnsiString)inet_ntoa(CliAddr.sin_addr);
  return CliIP;
}


Сделал так как написанно выше.
Только вот что не поятно, почему после простого завершения клиентского процеса(TerminateProcess) указанная выше функция всё равно возвращает клиентский IP.
Подскажите пожалуйста , как быть.
Заранее благодарен,
С уважением HAWK.

Это сообщение отредактировал(а) Олег2005 - 8.2.2011, 21:15
--------------------
воин dzen'a
PM MAIL   Вверх
Олег2005
Дата 8.2.2011, 21:22 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(hawk3500 @  8.2.2011,  19:23 Найти цитируемый пост)
И вот стала задача, как определить активен сокет на стороне клиента или нет.

Обычно это делается с помощью setsockopt() - опция SO_KEEPALIVE и TCP_KEEPALIVE.
Для указанного сокета модуль TCP самостоятельно будет посылать проверочные сегменты.

getsockname()
Функция возвращает адрес ЛОКАЛЬНОГО сокета
Применяется как правило на стороне сервера.....
getpeername() - возвращает адрес удаленного сокета....
PM MAIL WWW MSN   Вверх
hawk3500
Дата 8.2.2011, 22:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 246
Регистрация: 6.2.2009

Репутация: нет
Всего: 2



Т.е. вы советуйте выставить int WSAIoctl
struct tcp_keepalive alive;
DWORD dwRet, dwSize;

alive.onoff = 1;
alive.keepalivetime = 10000;
alive.keepaliveinterval = 1000;

dwRet = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),
  NULL, 0, reinterpret_cast<DWORD*>(&dwSize), NULL, NULL);

А потом после этого для проверки наличия активного соединения использовать getpeername()?
Как я понимаю в таком случае при отсутствии соединения в качестве IP клиента вернёться 0.
Я правильно понял Вашу мысль?

Добавлено @ 22:44
Просто не понимаю как используя проверочные сегменты для определения разрыва связи.
Как это событие отловить или проверить?

Это сообщение отредактировал(а) hawk3500 - 9.2.2011, 07:47
--------------------
воин dzen'a
PM MAIL   Вверх
Олег2005
Дата 9.2.2011, 20:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(hawk3500 @  8.2.2011,  21:32 Найти цитируемый пост)
Как я понимаю в таком случае при отсутствии соединения в качестве IP клиента вернёться 0.

Не должен быть 0.
getpeername() - возвращает адрес удаленного сокета - т.е того сокета, который произведен был аксептом для данного клиента.
Откуда берется адрес? - из таблицы соединений модуля TCP.
И будет для данного сокета оттуда "браться" - пока сервер не закроет это соединение close() -  и еще в течении почти 2 минут - еще будет эта запись висеть - cостояние TIME_WAIT.
В общем почитайте аттач



Присоединённый файл ( Кол-во скачиваний: 11 )
Присоединённый файл  _____________SO_KEEPALIVE.doc 34,00 Kb
PM MAIL WWW MSN   Вверх
hawk3500
Дата 9.2.2011, 22:11 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Бывалый
*


Профиль
Группа: Участник
Сообщений: 246
Регистрация: 6.2.2009

Репутация: нет
Всего: 2



Спасибо за мануал.
Если у Вас есть возможность поясните пожалуйста, а как использовать функцию select для определения FIN.
Если можно, то скажите как это сделать на примере:

Код

 int WSAIoctl
struct tcp_keepalive alive;
DWORD dwRet, dwSize;

alive.onoff = 1;
alive.keepalivetime = 10000;
alive.keepaliveinterval = 1000;

dwRet = WSAIoctl(sock, SIO_KEEPALIVE_VALS, &alive, sizeof(alive),
  NULL, 0, reinterpret_cast<DWORD*>(&dwSize), NULL, NULL);


И этот код, правильное применение WSAIoctl или нет?
--------------------
воин dzen'a
PM MAIL   Вверх
Олег2005
Дата 10.2.2011, 16:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Завсегдатай
Сообщений: 421
Регистрация: 26.5.2005
Где: Рига Латвия

Репутация: 6
Всего: 11



Цитата(hawk3500 @  9.2.2011,  21:11 Найти цитируемый пост)
Если у Вас есть возможность поясните пожалуйста, а как использовать функцию select для определения FIN.

Если на сокет пришел сегмент FIN - то сокет помещается в набор как разрешенный для чтения. 
Цитата(hawk3500 @  9.2.2011,  21:11 Найти цитируемый пост)
И этот код, правильное применение WSAIoctl или нет? 

С ходу не скажу.....
А почему не setsockopt()?
PM MAIL WWW MSN   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Сети | Следующая тема »


 




[ Время генерации скрипта: 0.1326 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.