The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
С & select, !*! PxeL, 14-Ноя-09, 16:15  [смотреть все]
Доброго всем!
Прошу cориентировать, может, не в сложном вопросе, но 4 книги (уже), как об стенку
Пишу программу - линейно работает, пытаюсь сделать много клиентной. Коментариями прописываю, что и как я понимаю - прошу поправить если не так.

int main(int argc, char *argv[]) {
...
int server_sockfd, client_sockfd;
...
listen (server_sockfd, 5);


int count = 0 ;
fd_set set, tset;
struct timeval timeout={2,0};

FD_ZERO (&set); //обнуляю set
FD_SET(server_sockfd, &set); //ввожу в set
while(1){ /

timeout.tv_sec = 1;
timeout.tv_usec = 1;
count = select (server_sockfd, &set, 0, 0, &timeout); //если select фиксирует изменения в сокете или в сет, то должно count получить что то.
if (count > 0) {
if (FD_ISSET (server_sockfd, &set) > 0) // смотрю на серверный сокет
{
...
client_sockfd = accept(...);
printf("%s:%d\n", inet_ntoa(client_address.sin_addr) , ntohs(client_address.sin_port));
FD_SET (client_sockfd, &set); // ввожу нового клиента в set
}

    for (client_sockfd = 0; client_sockfd < server_sockfd; ++server_sockfd) // перебираю клиентов
      if(client_sockfd != server_sockfd && FD_ISSET(client_sockfd, &set)) // если клиента нужно обслужить
    if (read_pack(&client_sockfd)>0) //просто выплевыает в терминал
      {
        (void) close (client_sockfd); // закрываю сокет
        FD_CLR (client_sockfd, &set); // убираю сокет с set
      }

;}
printf("select: %d\n",count); // что бы увидить состояние
;}


И не вижу изменения состояния select в результате
  • С & select, !*! PxeL, 18:11 , 14-Ноя-09 (1)
    результаты
    select (server_sockfd , &set, 0, 0, &timeout);
    и
    FD_ISSET (server_sockfd, &set)
    всегда равны нулю
    кажется все инклюды есть:
    #include <sys/types.h>
    #include <sys/socket.h>
    #include <sys/time.h>
    #include <stdio.h>
    #include <netinet/in.h>
    #include <arpa/inet.h>
    #include <unistd.h>
    #include <stdlib.h>
    #include <string.h>
    #include <math.h>
    • С & select, !*! Aesthetus Animus, 19:21 , 14-Ноя-09 (2)
      > select (server_sockfd, &set, 0, 0, &timeout);

      man select:
      >int
      >select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
      >    struct timeval *timeout);
      > ...
      > The first nfds descriptors are checked in each set; i.e., the
      > descriptors from 0 through nfds-1 in the descriptor sets are examined.

      В select надо передавать nfds равное (maxfd + 1), где mafd - соответсвует большему номеру из опрашиваемых дескрипторов. В Вашием случае при первом проходе maxfd равно server_sockfd.

      При добавлении в множество новых обслуживаемых дескрипторов нужно пересчитывать maxfd. Ценой производительности, можно вместо (maxfd + 1) передавать FD_SETSIZE.


  • С & select, !*! Гулевич А.И., 21:57 , 14-Ноя-09 (3)
    >[оверквотинг удален]
    >     FD_CLR (client_sockfd, &set); // убираю сокет с
    >set
    >   }
    >
    >;}
    >printf("select: %d\n",count); // что бы увидить состояние
    >;}
    >
    >

    >И не вижу изменения состояния select в результате

    После каждого select нужно заново делать FD_SET. Далее лучше использовать epoll. Там можно callback на обработку поставить вообще конгениально будет, но только linux.

    да, и select(N+1!,...).

  • С & select, !*! PxeL, 15:23 , 15-Ноя-09 (4)
    FD_SET(server_sockfd, &set);
    это означает, что значение! номера server_sockfd попадает в структуру FD_SET под именем set, тогда смысл после accept делать FD_SET (client_sockfd, &set), ведь этот индекс уже в структуре?

    count = select (n+1, &set, ...
    делает проверку на чтение - т.е. сюда попадает и пришедшие новые соединения и пришедшие пакеты на существующие соединения. а при переборе вызывается if (FD_ISSET (i, &set) > 0). Тогда получается что нужно вести учет какие индексы портов (дескрипторы, как если я правильно понимаю термин) уже подключены и делать проверку соответственную.

    Я понимаю, что ядро само устанавливает "линк" дескриптора порта в прогамме к самому порту. А индекс дескрипторов - единый, тоесть если я создам с прогаммы соединение, то дескриптор клиентского порта при переборе будет мешать мне без собственной индексации (где буду знать, что подклчать, что читать, а что закрыть)

    Спасибо за ответы. Каждый новый ответ пророждает уйму новых вопросов :)

  • С & select, !*! PxeL, 19:48 , 16-Ноя-09 (5)
    Такое ощущение, что вся русскоязычная литература - кастрирована. толь редакторами, толь переводчиками... а может и сами авторы пишут, сами не знают о чем, т.к. ошибок и противоречий уйма...
    Может ктонить разтолковать как распределяются дескрипторы сокетов? и как с ними правильно оперировать в селекте? человеческим русским языком.
    • С & select, !*! jd, 16:50 , 18-Ноя-09 (6)
      Весьма путанно изъясняетесь, так что не обессутьте, если ответ не очень по теме.

      Принцип, по которому выделяются файловые дескрипторы, не важно, для сокетов или для обычных файлов, не оговаривается. То есть вы получаете целое число, которое в данном процессе является ссылкой на сокет и больше вам ничего знать не нужно. Ясно, что большинство реализаций будут выделять числа, идущие подряд по возрастанию, но строить на этом предположении логику программы, особенно если она больше трёх строчек, ни в коем случае не стоит.

      Что касается "и как с ними правильно оперировать в селекте" - вопрос не вполне ясен. Если вам не ясно, что передавать в качестве первого параметра select(), то: нужно найти максимум среди всех проверяемых этим select'ом дескрипторов (целых чисел, как я уже говорил), увеличить полученное число на еденицу и вот это и передавать. Про FD_SET, который нужно делать перед каждым select'ом, вроде бы уже писали выше. Если вам не ясно что-то другое, задавайте вопрос чётче.

      • С & select, !*! PxeL, 20:18 , 18-Ноя-09 (7)
        1. серверный сокет (принимающий на акцепт) - он всегда один, по сле определения биндом ( нашел более менее толковую книгу).
        2. сокет приняты акцептом после проверки на чтение говорит, что есть чтение, но реально при попытке вычитать операция рид возвращает -1. В талмуте оговорено, что возможно RST, но как от него избавиться? т.к. оно почему-то всегда происходит.
        3. Ну что, нельзя было сказать сразу, что направильно думаешь, что на акцепт просматривать нужно только 1 сокет... и т.п.
        могу привести почти с десяток книг, где авторы дают описания этой функции "как кот наплакал" - неичего не описывая, и только пару слов о какойнеть одной особенности, а судя по примерам, можно сказать, что вообще не соображают что демонстрируют. А на форуме, хоть пассатижами выжимай.
        • С & select, !*! jd, 02:48 , 19-Ноя-09 (8)
          >1. серверный сокет (принимающий на акцепт) - он всегда один, по сле
          >определения биндом ( нашел более менее толковую книгу).

          Он, ясное дело, один, но к чему вы это - непонятно.

          >2. сокет приняты акцептом после проверки на чтение говорит, что есть чтение,
          >но реально при попытке вычитать операция рид возвращает -1. В талмуте
          >оговорено, что возможно RST, но как от него избавиться? т.к. оно
          >почему-то всегда происходит.

          "возвращает -1" - недостаточно информации. Кроме возвращаемого значения есть ещё errno, который говорит, почему вернулось -1.

          >3. Ну что, нельзя было сказать сразу, что направильно думаешь, что на
          >акцепт просматривать нужно только 1 сокет... и т.п.
          >могу привести почти с десяток книг, где авторы дают описания этой функции
          >"как кот наплакал" - неичего не описывая, и только пару слов
          >о какойнеть одной особенности, а судя по примерам, можно сказать, что
          >вообще не соображают что демонстрируют. А на форуме, хоть пассатижами выжимай.

          Не знаю, где и что вы прочитали, но надо понимать, что книги, являющиеся обзором большого количества тем, не могут вместить подробное описание каждой из них, а описывают наиболее распространённые и простые случаи. Обычно, если нужно более детальное изучение вопроса, смотрят в сторону более специализированной литературы. Библией для сетевого разработчика считается "UNIX. Разработка сетевых приложений" Стивенса сотоварищи. Но в принципе и в интернете можно достаточно информации найти.

          Что касается вашего случая, опишите детально, что вы хотите получить и в чём конкретно у вас проблемы, вместо того, чтобы приводить неработающий код, разбираться в котором никому неохота (да и дело может быть не в коде, а в самом пути решения задачи), и тогда вам скорее подскажут что-то по делу.




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

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