На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Oпределения завершения чтения из сокета , Название не понятное, подробности внутри :-)
    Чтоб объяснить проблему приведу простой пример:

    Пример #1K: (ns - сокет)

    ...
    ...
    char buf[1024];
    int nbytes, len;

    for(;;) {
    nbytes = recv (ns, buf, sizeof (buf) - 1, 0);
    buf[nbytes] = '\0';
    len = strlen (buf);
    cout << buf;
    if (buf[nbytes-1]=='\n' && buf[nbytes-2]=='\n') break;
    if (len < 1024) break;
    }
    ...
    ...


    В данном примере последовательность символов "\n\n" приводит к завершению приёма сообщения, так-же к завершению его приема приводит ситуация когда сообщение будет < 1024 cимволов, однако мне это не подходит. Например если клиент шлет не всё сообщение сразу (телнетом например) то прием обламываеться после первой части если она меньше чем 1024. Даже если я начну читать из сокета посимвольно то после завершения этой первой части опять сработает break. Можно конечно отбросить break и ждать/читать пока не появиться \n\n НО тогда возникает проблема: если вдруг произойдет ошибка на стороне клиента (или во время передачи данных) то сервер "\n\n" не получит никогда и процесс просто зависнет.

    В общем может кто-нибудь может что-то посоветовать?

    Заранее спасибо!

    Добавлено в :
    Задам даже более конкретный вопрос: можно ли как-то выставить таймаут для функции recv() ?
    Сообщение отредактировано: Michail04 -
      Цитата
      Michail04, 7.02.04, 22:38
      Задам даже более конкретный вопрос: можно ли как-то выставить таймаут для функции recv()
      Использовать в цикле poll или select с достаточно малым тайм-аутом и читать до получения требуемых данных или ошибки.

      Добавлено в :
      Считывание данных из сокета.

      Добавлено в :
      По ссылке, правда, под Win, но отклонения там небольшие. :)
        Цитата trainer,7.02.04, 23:56
        Использовать в цикле poll или select с достаточно малым тайм-аутом и читать до получения требуемых данных или ошибки.

        Тогда вопрос по select. Нашел я в мане пример:

        Цитата

        #include <stdio.h>
        #include <sys/time.h>
        #include <sys/types.h>
        #include <unistd.h>

        int
        main(void)
        {
        fd_set rfds;
        struct timeval tv;
        int retval;

        /* Ждем, пока на стандартном вводе (fd 0) что-нибудь
        появится. */
        FD_ZERO(&rfds);
        FD_SET(0, &rfds);
        /* Ждем не больше пяти секунд. */
        tv.tv_sec = 5;
        tv.tv_usec = 0;

        retval = select(1, &rfds, NULL, NULL, &tv);
        /* Не полагаемся на значение tv! */

        if (retval)
        printf("Данные доступны.\n");
        /* Теперь FD_ISSET(0, &rfds) вернет истинное значение. */
        else
        printf("Данные не появились в течение пяти секунд.\n");

        exit(0);
        }


        Так вот как мне вместо fd_set rfds заставить работать с дескриптором сокета?
        Сообщение отредактировано: Michail04 -
          Посмотри в ФАКе на эту тему стаью AQL: Тут
            Пробую следующее и всегда вылетаю в timeout

            Цитата

            ...
            ...
            int sel = 0;
            timeval r_timeout;

            fd_set fds;
            FD_ZERO(&fds);
            FD_SET(ns, &fds); // ns - сокет

            r_timeout.tv_sec = 0;
            r_timeout.tv_usec = 15000000;

            sel = select(0, &fds, NULL, NULL, &r_timeout);

            if(!sel) {
            cout << "Timeout\n";
            return 0;
            }

            if(sel < 0) {
            cout << "Error\n";
            return -1;
            }

            return1;


            p.s. прочитав man select и обнаружив строчку: n на единицу больше самого большого номера дескриптора из всех наборов. (n - первый аргумент) попробовал:

            Цитата
            ...
            sel = select(ns+1, &fds, NULL, NULL, &r_timeout);
            ...


            но это дает тот же результат


            Что я делаю не так?
              А если написать:
              ExpandedWrap disabled
                r_timeout.tv_sec  = 15;
                r_timeout.tv_usec = 0;
                C
                Цитата
                r_timeout.tv_sec = 15;
                r_timeout.tv_usec = 0;


                как ни странно заработало:-)

                Сэнкс!
                1 пользователей читают эту тему (1 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script execution time: 0,0297 ]   [ 15 queries used ]   [ Generated: 21.05.24, 16:32 GMT ]