The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  ВХОД  слежка  RSS
"Проверка клиентского сокета со стороны сервера"
Вариант для распечатки Архивированная нить - только для чтения! 
Пред. тема | След. тема 
Форумы Программирование под UNIX (Public)
Изначальное сообщение [Проследить за развитием треда]

"Проверка клиентского сокета со стороны сервера"
Сообщение от FrOdO emailИскать по авторуВ закладки on 21-Ноя-03, 13:24  (MSK)
Всем привет.

Можно ли как-нибудь проверить со стороны сервера, а есть ли соединение с клиентом, чтобы определить когда следует выходить из цикла чтения данных из сокета. Насколько я понял, команда recv будет ждать данных, пока не получит хоть байт. Можно конечно ввести timeout и проверять его, но может есть что-то другое?

Заранее благодарю за ответы.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

 Оглавление

Индекс форумов | Темы | Пред. тема | След. тема
Сообщения по теме

1. "Проверка клиентского сокета со стороны сервера"
Сообщение от divan emailИскать по авторуВ закладки on 21-Ноя-03, 14:34  (MSK)
>Всем привет.
>
>Можно ли как-нибудь проверить со стороны сервера, а есть ли соединение с
>клиентом, чтобы определить когда следует выходить из цикла чтения данных из
>сокета. Насколько я понял, команда recv будет ждать данных, пока не
>получит хоть байт. Можно конечно ввести timeout и проверять его, но
>может есть что-то другое?
>
>Заранее благодарю за ответы.

Насколько я понимаю, если recv возвращает ноль - то это диссконект. Тогда и выходим из цикла..

  Рекомендовать в FAQ | Cообщить модератору | Наверх

2. "Проверка клиентского сокета со стороны сервера"
Сообщение от FrOdO emailИскать по авторуВ закладки on 21-Ноя-03, 15:42  (MSK)

>Насколько я понимаю, если recv возвращает ноль - то это диссконект. Тогда
>и выходим из цикла..

А где сказано, что это дисконнект? Это просто означает, что ничего нет в буфере. А если, допустим, клиент работает по медленным каналам, то я просто отшибу его, если выйду из цикла, или я не прав?

Спасибо за внимание.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

3. "Проверка клиентского сокета со стороны сервера"
Сообщение от vnp emailИскать по авторуВ закладки on 21-Ноя-03, 21:36  (MSK)
>
>>Насколько я понимаю, если recv возвращает ноль - то это диссконект. Тогда
>>и выходим из цикла..
>
>А где сказано, что это дисконнект?

В man recv :)

>Это просто означает, что ничего нет
>в буфере. А если, допустим, клиент работает по медленным каналам, то
>я просто отшибу его, если выйду из цикла, или я не
>прав?
>

Если сокет блокирующий, то пока просто нет данных, recv не вернется. Если не блокирующий, то в отсутствие данных вернется -1 с errno EAGAIN (или EWOULDBLOCK).

>Спасибо за внимание.


  Рекомендовать в FAQ | Cообщить модератору | Наверх

4. "Проверка клиентского сокета со стороны сервера"
Сообщение от FrOdO emailИскать по авторуВ закладки on 24-Ноя-03, 10:00  (MSK)
>В man recv :)

Всегда смотрю прежде, чем писать куда-либо

>>Это просто означает, что ничего нет
>>в буфере. А если, допустим, клиент работает по медленным каналам, то
>>я просто отшибу его, если выйду из цикла, или я не
>>прав?
>
>Если сокет блокирующий, то пока просто нет данных, recv не вернется. Если
>не блокирующий, то в отсутствие данных вернется -1 с errno EAGAIN

Понимаю, но НЕ ВОЗВРАЩАЕТ он -1 при закрытии соединения клиентом. 0 - постоянно.
Ладно, бог с ним, повешу timeout.

Спасибо за ответы.

  Рекомендовать в FAQ | Cообщить модератору | Наверх

5. "Проверка клиентского сокета со стороны сервера"
Сообщение от scum Искать по авторуВ закладки on 25-Ноя-03, 18:52  (MSK)
Не надо вешать нос. Все просто решается, посмотри инфу про неблокируемые сокеты, а потом маны на select() или poll(), какая больше понравится, и все дела.
  Рекомендовать в FAQ | Cообщить модератору | Наверх

6. "Проверка клиентского сокета со стороны сервера"
Сообщение от FrOdO emailИскать по авторуВ закладки on 26-Ноя-03, 18:56  (MSK)
Посмотрел и вот что сделал:

void TDaemon::MainLoop()
{
  char buffer[256];
  int ret_code;
  timeval tv;
  fd_set rfds;

  while(true)
  {
    if(!sock->Listen() && (clientSID = sock->Accept(0, 0)))
    {
      puts("\nNew Connection\n");

      while(true)
      {
        FD_ZERO(&rfds);
        FD_SET(clientSID, &rfds);
        tv.tv_sec = timeout;
        tv.tv_usec = 0;

        int ret = select(clientSID + 1, &rfds, NULL, NULL, &tv);

        if(!ret && FD_ISSET(clientSID, &rfds))
          break;

        puts("\nNew Cycle\n");

        while(sock->Read(buffer, 255, 0, clientSID) > 0)
          printf("\nServer: %s\n", buffer);
      }
    }
  }
}

Насколько я понял select либо дождется данных либо вывалится по timeout.
Если она дожидается данных, то начинает работать цикл с Read. После того как данные кончаются, по логике нужно заново вызывать select и ждать еще данных. Но у меня, после того как я считал все данные (Read возвращает 0), select, при следующей итерации, сразу говорит, что данные есть, хотя Read ничего не считывает (реально нет данных) и программа входит в бесконечный цикл. Правильно ли ведет себя select?
Read, Listen, Accept - непосредственно вызывают функции recv, listen, accept соответственно (это inline методы класса содержащие только вызовы описанных функций).

  Рекомендовать в FAQ | Cообщить модератору | Наверх

7. "Проверка клиентского сокета со стороны сервера"
Сообщение от XMan Искать по авторуВ закладки on 26-Ноя-03, 19:59  (MSK)
> Понимаю, но НЕ ВОЗВРАЩАЕТ он -1 при закрытии соединения клиентом. 0 - постоянно.


Ну так он и должен 0 возвращать. Если клиент висит и ничего не посылает, recv может годами ожидать данных без возврата. Если recv вернул "-1", то это ошибка или прерывание (errno == EINTR). Если он вернул 0 - клиент закрыл соединение.

Для неблокирующих сокетов почти то же самое, за исключением того, что при отсутствии в буфере данных и присутствии соединения recv вернет "-1" и код EAGAIN в errno.

Кстати, ты уверен, что у тебя именно неблокирующий сокет ? Функцией socket создается обычный блокирующий, а потом он должен доводиться функцией fcntl, если нужен неблокирующий.

PS. Хотя использование select - это более правильно :)

  Рекомендовать в FAQ | Cообщить модератору | Наверх


Удалить

Индекс форумов | Темы | Пред. тема | След. тема
Пожалуйста, прежде чем написать сообщение, ознакомьтесь с данными рекомендациями.




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру