URL: https://www.opennet.me/cgi-bin/openforum/vsluhboard.cgi
Форум: vsluhforumID9
Нить номер: 6994
[ Назад ]

Исходное сообщение
"Как отследить закрытие сокета"

Отправлено zkrvova , 30-Ноя-07 11:48 
Значит есть серверная програмка которая общается с клиентами используя неблокирующие сокеты.

Вот такая вот функция следит за данными:

        FD_ZERO(&rfds);
        FD_SET(sid, &rfds);

        if (select(sid+1, &rfds, NULL, NULL, &tv) > 0){
                return read(sid, buf, PACKET_SIZE-1);
        }else{
                return -1;
        }

Но если клиент закрывает свой сокет то моя задача сразу закрывается, а хотелось бы самому обрабатывать закрытие, т.к. надо перед закрытием ещё чтото сделать.


Содержание

Сообщения в этом обсуждении
"Как отследить закрытие сокета"
Отправлено vic , 30-Ноя-07 12:06 
>[оверквотинг удален]
>            
>    return read(sid, buf, PACKET_SIZE-1);
>        }else{
>            
>    return -1;
>        }
>
>Но если клиент закрывает свой сокет то моя задача сразу закрывается, а
>хотелось бы самому обрабатывать закрытие, т.к. надо перед закрытием ещё чтото
>сделать.

четвертый параметр селекта как раз и служит для обработки ошибочных эвентов.


"Как отследить закрытие сокета"
Отправлено zkrvova , 30-Ноя-07 12:30 
>[оверквотинг удален]
>>        }else{
>>            
>>    return -1;
>>        }
>>
>>Но если клиент закрывает свой сокет то моя задача сразу закрывается, а
>>хотелось бы самому обрабатывать закрытие, т.к. надо перед закрытием ещё чтото
>>сделать.
>
>четвертый параметр селекта как раз и служит для обработки ошибочных эвентов.

А можно маленький примерчик?
Ато везде об этом вскользь и во всех примерах он незадействован.


"Как отследить закрытие сокета"
Отправлено vic , 30-Ноя-07 19:09 
>[оверквотинг удален]
>>>        }
>>>
>>>Но если клиент закрывает свой сокет то моя задача сразу закрывается, а
>>>хотелось бы самому обрабатывать закрытие, т.к. надо перед закрытием ещё чтото
>>>сделать.
>>
>>четвертый параметр селекта как раз и служит для обработки ошибочных эвентов.
>
>А можно маленький примерчик?
>Ато везде об этом вскользь и во всех примерах он незадействован.

Если сокет закрыт то либо селект вернет ошибку неверный дескриптор, либо в сете errfds будет обозначен этот дескриптор. Нуна эксперимент, я не пробовал, а искать лень.


"Как отследить закрытие сокета"
Отправлено Аноним , 02-Дек-07 22:52 
>Значит есть серверная програмка которая общается с клиентами используя неблокирующие сокеты.
>Вот такая вот функция следит за данными:
>...
>Но если клиент закрывает свой сокет то моя задача сразу закрывается, а
>хотелось бы самому обрабатывать закрытие, т.к. надо перед закрытием ещё чтото
>сделать.

А пишешь ты тоже с проверкой?

Сдаётся мне, что твоя программа по SIGPIPE завершает работу, когда ты пытаешься отправить в закрытый другой стороной сокет.



"Как отследить закрытие сокета"
Отправлено zkrvova , 03-Дек-07 10:42 
>[оверквотинг удален]
>>Вот такая вот функция следит за данными:
>>...
>>Но если клиент закрывает свой сокет то моя задача сразу закрывается, а
>>хотелось бы самому обрабатывать закрытие, т.к. надо перед закрытием ещё чтото
>>сделать.
>
>А пишешь ты тоже с проверкой?
>
>Сдаётся мне, что твоя программа по SIGPIPE завершает работу, когда ты пытаешься
>отправить в закрытый другой стороной сокет.

да нет, у меня данные посылаются только в том случае если пришёл запрос, а запрос явно не приходил, проверял.


"Как отследить закрытие сокета"
Отправлено f00l , 03-Дек-07 16:50 
>[оверквотинг удален]
>            
>    return read(sid, buf, PACKET_SIZE-1);
>        }else{
>            
>    return -1;
>        }
>
>Но если клиент закрывает свой сокет то моя задача сразу закрывается, а
>хотелось бы самому обрабатывать закрытие, т.к. надо перед закрытием ещё чтото
>сделать.

Ну гдето вот так, тестовый код сервера, прием данных с определенного connect в не блокируешем режиме:

memset( buff , 0 , SIZE_BUFF_RECEIV  );
check = recv(connect , buff , SIZE_BUFF_RECEIV , 0);
if(check == 0){
   if(timeout <= time(NULL)){
     check = send(connect , buff , 1 , 0);
     if(check == -1){
      //delet_connect;
      break;
     }
     timeout = time(NULL) + timeout_check;
     continue;
   }
}
if(check == -1){
  if(errno != EAGAIN){
    //delet_connect
    break;
  }
  else{
     if(timeout <= time(NULL)){
       check = send(connect , buff , 1 , 0);
       if(check == -1){
         //delet_connect
         break;
       }
       timeout = time(NULL) + timeout_check;
       continue;
     }
   }
}
else{
   // пришли данные
   timeout = time(NULL) + timeout_check;
}