Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как проверить сотояние сокета?  (Прочитано 12009 раз)
0 Пользователей и 1 Гость смотрят эту тему.
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« : 15-09-2006 07:19 » 

В примерах по сокетам, закрытие сокета обычно отлавливают  через FD_CLOSE
if (!WSAEventSelect(sSoc , EvWSA, FD_READ | FD_CLOSE))
             WSAResetEvent(EvWSA );
     if (WSAWaitForMultipleEvents( 1, &EvWSA , false, TimeOut, false)!=WSA_WAIT_FAILED)
     {
  ;
                if(!WSAEnumNetworkEvents(sSoc , EvWSA, &wsEvents))

                    if(wsEvents.lNetworkEvents & FD_CLOSE)
              {
                  
                  isActive=false;
                  return ERR;

                    }

Мне нужно  не вцикле опроса а внеком произвольном месте изнать не закрыт ли сокет? Как это проще сделать иначе как 


if (!WSAEventSelect(sSoc , EvWSA, FD_CLOSE))
             WSAResetEvent(EvWSA );
     if (WSAWaitForMultipleEvents( 1, &EvWSA , false, 0, false)!=WSA_WAIT_FAILED)
     {
                // Дествия по закрытию сокета
             }
               
и сработает ли этот варинт на уже закрытом сокете по которому уже поймали FD_CLOSE ?   
Записан

Да да нет нет все остальное от лукавого.
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 15-09-2006 08:16 » 

В продолжение

 f=WSAWaitForMultipleEvents( 1, &lEvWSA , false, 0, false);
             if (f!=WSA_WAIT_FAILED)
         {
            if(!WSAEnumNetworkEvents(sSoc , EvWSA, &wsEvents))
            
               if(wsEvents.lNetworkEvents & FD_CLOSE)

Отрабатывает этот кусок WSAWaitForMultipleEvents возвращает 258 те что то там произошло  но wsEvents.lNetworkEvents ==0 Не понялНе понял?? Почему?
Записан

Да да нет нет все остальное от лукавого.
sss
Специалист

ru
Offline Offline

« Ответ #2 : 19-10-2006 01:51 » 

А зачем так сложно?
Закрытие сокета может происходить в трех случаях:
1) Сокет закрывается твоим кодом
2) Нормальное завершение с удаленной стороны
3) Аварийное завершение с удаленной стороны

В случае 1 - вообще нет проблем, во 2 ты получаешь 0 из сети.
Вот случай 3 это тяжело. Ты получишь 0, например, если задача завершена с удаленной стороны даже с помощью TerminateProcess. А вот в случае с обрывом провода... Некоторое количество пакетов все равно ставятся в очередь отправки клиенту без ошибок. Потом, после определенного интервала времени или N-го числа неотправленых пакетов, не знаю точно, при отправке возникнет ошибка "Указанное сетевое имя более недоступно."
Записан

while (8==8)
sss
Специалист

ru
Offline Offline

« Ответ #3 : 19-10-2006 02:13 » 

Уточнил, после разрыва, если нет обмена с клиентом, сервер может простоять, считая что с клиетом все хорошо сколько угодно (простоял 10 минут). Потом, разрыв не устранен, операция send завершилась удачно, однако, после 3 минут возникла ошибка "Указанное сетевое имя более недоступно." Я использую порт завершения. Ошибка возникает в виде выхода потока пула порта из ожидания на функции GetQueuedCompletionStatus() с возвратом FALSE. в общем дам совет - используй в серверном решении порт завершения. Очень удобная, предсказуемая вещь.
« Последнее редактирование: 19-10-2006 02:16 от sss » Записан

while (8==8)
PSD
Главный специалист

ru
Offline Offline
Пол: Мужской

« Ответ #4 : 19-10-2006 05:44 » 

Что есть "порт завершения"?(в краце...)
Записан

Да да нет нет все остальное от лукавого.
sss
Специалист

ru
Offline Offline

« Ответ #5 : 19-10-2006 06:33 » new

Совокупность структур в недрах системы. Ты создаешь пару - тройку потоков и привязываешь к порту. Скажем это будут рабочие в пуле порта. Точка входа рабочих зацикливается на операцию
GetQueuedCompletionStatus(). Они входят в эту функцию ожидания и приостанавливаются. Далее, в основном потоке, ты создаешь сокеты и добавляешь к этому же порту функцией CreateIoCompletionPort (там же можно указать контекст!). После привязки сетевая операция выполняются асинхронно. После окончания (операции) один из рабочих в пуле оживает и выходит из ожидания, "перенося" информацию контекста и статуса завершения.
Записан

while (8==8)
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines