На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (2) [1] 2  все  ( Перейти к последнему сообщению )  
    > Пишем синхронный http сервер с нуля на boost::asio , не полуачается отправить страничку клиенту
      Здравствуйте. Решил написать самый простой http сервер на asio.


      ExpandedWrap disabled
        #include <boost/asio.hpp>
         
        #include <thread>
         
         
        using boost::asio::ip::tcp;
         
        const char data[]="HTTP/1.0 200 OK\r\n"
              "Content-Length: 67\r\n"
              "Content-Type: text/html\r\n"
              "\r\n"
              "<html><body>The quick brown fox jumps over the lazy dog<br/><body/>";
         
         
        void session(tcp::socket sock)
        {
         
          sock.send(boost::asio::buffer(data, sizeof(data));
         }
         
        int main(int argc, char *argv[])
        {
          boost::asio::io_service io_service;
          tcp::acceptor a(io_service, tcp::endpoint(tcp::v4(), 80));
         
          for (;;)
          {
            tcp::socket sock(io_service);
            a.accept(sock);
            std::thread(session, std::move(sock)).detach();
          }
         
         
          return 0;
        }


      Запускаю браузер. И страничка то отображается, то нет. В чем проблема -не могу понять. Когда у клинта происходит ошибка,то пишет, Sockert Error 1024. Connection reset by peer.

      Помогите пожалуйста разобраться.
        сокет разрушается быстрее, чем успевает выполниться send
          Кстати да, дропать сокет сразу после отсылки - не самая лучшая идея. Исходя хотя бы из того, что некоторые HTTP-соединения будут keep-alive (всё ж версия HTTP 1.1 уже давно стала стандартом де-факто, поэтому вполне возможен вариант, что никто не проверяет Ваш HTTP/1.0).
          http://www.lib.ru/WEBMASTER/rfc2068/section-8.html
            Клиент и сервер - на одной машине?
            Цитата UncleBob @
            сокет разрушается быстрее, чем успевает выполниться send

            Такое возможно, и в API это решается с помощью SO_LINGER.
            Правда данные слишком маленькие.
            Поэтому может дело в алгоритме Nagle?
            Сообщение отредактировано: Oleg2004 -
              Цитата Oleg2004 @
              Такое возможно, и в API это решается с помощью SO_LINGER.

              Да там же объект сокета убивается сразу после запуска потока... Если поток успел отработать, то есть шанс, что данные послались, а если продолжилось выполнение главного - пока-пока...
                Цитата UncleBob @
                Да там же объект сокета убивается сразу после запуска потока.

                Я не особенный поклонник буста, потому в коде почему то этого не вижу <_<
                Ткните, где это - буду очень признателен. Век живи, век учись :)
                  Цитата iSherhan @
                  tcp::socket sock(io_service);

                  здесь создается с++ объект sock типа tcp::socket

                  он будет удален при выходе за область видимости, то есть при завершении шага цикла.

                  далее, я не уверен, что именно делает std::move, это какая-то новая фишка с++, которым я уже не занимаюсь много лет, но по тому что я вычитал, не похоже, чтобы она каким-то образом могла помешать удалению объекта sock, а как я подозреваю, удаление объекта влечет закрытие содержащегося в нем сокета.
                    Мне кажется что если бы было в точности так, то у автора не было бы возможности вообще что получить хоть раз.
                    Цитата iSherhan @
                    Запускаю браузер. И страничка то отображается, то нет.

                    Кроме того, при возврате к началу бесконечного цикла он снова создает сокет - правда уже другой
                    Впрочем, автор замолчал... <_<
                    Сообщение отредактировано: Oleg2004 -
                      Цитата Oleg2004 @
                      Мне кажется что если бы было в точности так, то у автора не было бы возможности вообще что получить хоть раз.

                      Как раз описанное автором подтверждает мое предположение, потому как все зависит от того, успеет ли сработать поток до завершения цикла (что вполне возможно), или нет. И если успевает - то все ок, а если нет, то сокет закрывается до send. А дальше - как шедулеру заблагорассудится.
                        Кажется я начинаю что-то понимать.
                        Вы хотите сказать, что вызов
                        std::thread(session, std::move(sock)).detach();
                        приводит к созданию асинхронного по отношению к основному процессу потока...
                        Ну вот, если это так, то ваше предположение вполне... :)
                          Цитата Oleg2004 @
                          Вы хотите сказать

                          :yes:
                            Цитата UncleBob @
                            далее, я не уверен, что именно делает std::move, это какая-то новая фишка с++, которым я уже не занимаюсь много лет, но по тому что я вычитал, не похоже, чтобы она каким-то образом могла помешать удалению объекта sock

                            Но как раз это и происходит :) Это перемещение. Т.е. созданный в цикле сокет оказывается в функции
                            ExpandedWrap disabled
                              void session(tcp::socket sock)

                            В данном вопросе всё валидно.

                            Добавлено
                            Ну, а проблема, очевидно, в этом
                            Цитата
                            Remarks

                            The send operation may not transmit all of the data to the peer. Consider using the write function if you need to ensure that all data is written before the blocking operation completes.
                              Цитата MyNameIsIgor @
                              Ну, а проблема, очевидно, в этом

                              Наврядли. Функция send()ничего не шлет в сеть, она лишь копирует из своего буфера в передающий буфер сокета модуля TCP. Приемный буфер сокета в модуле TCP по умолчанию достаточно велик в разных ОС - В Беркли-реализациях по умолчанию используются буфера отправки и приема размером в 4096 байт, более современные системы используют буфера размером от 8192 до 61 440 байт.
                              А потому send() не сможет отправить свой буфер только тогда, когда буфер отправки сокета не может вместить данные из буфера приложения. В данном случае send() отправляет настолько мало данных, что этот вопрос даже и не встает. И они уходят совершенно спокойно без блокировки..
                                Цитата Oleg2004 @
                                Наврядли.

                                Зачем предполагать, если ТС может легко проверить? :blink:
                                  Цитата MyNameIsIgor @
                                  Зачем предполагать, если ТС может легко проверить?

                                  А шо такое TC? Total Commander? :blink:
                                  И если легко, то почему топикстартер не смог?
                                  А насчет предположений...
                                  Видите ли - все, что имеет коммерческое происхождение - как правило 100% работает.
                                  А вот любительский код - он таким и остается.
                                  Теоретические и практические консидерации по поводу send() известны уже лет 20 не менее.. и абсолютно детерминированы. А топикстартеру я бы порекомендовал сюда
                                  Насчет ТС...круто :lool:
                                  А бы не догадался никогда... :wall:
                                  Сообщение отредактировано: Oleg2004 -
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0,0752 ]   [ 16 queries used ]   [ Generated: 27.04.24, 09:06 GMT ]