На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Страницы: (3) 1 [2] 3  все  ( Перейти к последнему сообщению )  
    > Помогите разобраться boost::asio , решил переписать сетевую часть на бусте
      С чтением вопрос. Гарантирует ли такая конструкция буста что я получу на выходе все данные которые ожидаю получить?
      ExpandedWrap disabled
        void connection::do_read_body( int datalength )
        {
            auto self( shared_from_this( ) );
                
            m_socket.async_read_some(boost::asio::buffer(m_recvbuffer, datalength), [this, self](boost::system::error_code ec, std::size_t length)
            {
                if( !ec )
                {
                    //is datalength ==  length ?????
                }
            }
        }


      + есть непонятка как остановить io_service прервав во всех потоках прием данных и ожидание коннекта
      io_service.stop() не обеспечивает остановку всего
      Сообщение отредактировано: progman -
        Цитата progman @
        Гарантирует ли такая конструкция буста что я получу на выходе все данные которые ожидаю получить?

        Цитата http://www.boost.org/doc/libs/1_38_0/doc/h..._read_some.html
        The read operation may not read all of the requested number of bytes. Consider using the async_read function if you need to ensure that the requested amount of data is read before the asynchronous operation completes.


        Добавлено
        Цитата progman @
        не обеспечивает остановку всего

        Что это значит? У меня все работает, только нужно дождаться завершения потоков, где вызвана io_sevice.run().
        Сообщение отредактировано: Oleg2004 -
          Цитата shm @
          Что это значит? У меня все работает, только нужно дождаться завершения потов, где вызвана io_sevice.run().

          у меня после вызова io_service.stop() крашится все где то внутри буста
            Цитата progman @
            у меня после вызова io_service.stop() крашится все где то внутри буста

            Как потоки создаешь?
              Цитата shm @
              Цитата progman @
              у меня после вызова io_service.stop() крашится все где то внутри буста

              Как потоки создаешь?

              ExpandedWrap disabled
                 hWorkerThread = CreateThread( NULL, 0, serverPool, this, 0, &dwThreadId );


              ExpandedWrap disabled
                DWORD WINAPI workerThread::serverPool( LPVOID lpvParam )
                {
                    return (( workerThread* )lpvParam)->thread();
                }
                 
                int workerThread::thread( )
                {
                    mWorkerThread = this;
                 
                    try
                    {
                        server s( m_dbpool, io_service, m_serverport );
                        
                        io_service.run();
                    }
                 
                    catch (std::exception& e)
                    {
                        std::cerr << "Exception: " << e.what() << "\n";
                    }
                 
                    return 0;
                }
                Цитата progman @
                CreateThread

                попробуй заменить на _beginthreadex. А еще лучше на boost::thread, тогда переходник serverPool и не нужен будет.
                  progman, решил проблему?
                    Цитата shm @
                    progman, решил проблему?

                    нет (
                    у меня на сервере #include <boost/thread.hpp> вызывает кучу ошибок в компиляции ( windows web server 2008 R2 ) - я приложение собираю на удаленном сервере который полностью идентичен рабочим серверам пула.
                    при этом на моей локальной машине ( windows 10 ) все ок.
                    Студия в обоих случаях 2013 professional
                    Boost билдился с одинаковыми параметрами.

                    Поскольку критической важности нету я пока забил - занимаюсь текучкой ( дрючу оболтусов своих :crazy: а то расслабились )
                    Будет время нагуглю как решать траблу а то даже в X-COM 2 поиграть некогда (((

                    Скрытый текст
                    1> workerThread.cpp
                    1>C:\SERVER\LIBS\boost_1_60_0\boost/type_traits/common_type.hpp(111): fatal error C1001: An internal error has occurred in the compiler.
                    1> (compiler file 'f:\dd\vctools\compiler\cxxfe\sl\p1\c\esumem.c', line 8636)
                    1> To work around this problem, try simplifying or changing the program near the locations listed above.
                    1> Please choose the Technical Support command on the Visual C++
                    1> Help menu, or open the Technical Support help file for more information
                    1> C:\SERVER\LIBS\boost_1_60_0\boost/type_traits/common_type.hpp(133) : see reference to class template instantiation 'boost::type_traits_detail::common_type_impl<T1,T2>' being compiled
                    1> with
                    1> [
                    1> T1=int_least64_t
                    1> , T2=int_least64_t
                    1> ]
                    1> C:\SERVER\LIBS\boost_1_60_0\boost/type_traits/common_type.hpp(139) : see reference to class template instantiation 'boost::type_traits_detail::common_type_decay_helper<T1,T2,__int64,__int64>' being compiled
                    1> with
                    1> [
                    1> T1=int_least64_t
                    1> , T2=int_least64_t
                    1> ]
                    1> C:\SERVER\LIBS\boost_1_60_0\boost/chrono/duration.hpp(405) : see reference to class template instantiation 'boost::common_type<Rep1,Rep2>' being compiled
                    1> with
                    1> [
                    1> Rep1=int_least64_t
                    1> , Rep2=int_least64_t
                    1> ]
                    1> C:\SERVER\LIBS\boost_1_60_0\boost/thread/win32/basic_timed_mutex.hpp(211) : see reference to class template instantiation 'boost::common_type<boost::chrono::system_clock::duration,boost::chrono::system_clock::duration>' being compiled
                    1> SendingList.cpp
                    1>c1xx : fatal error C1060: compiler is out of heap space
                    1> Note: non-fatal system error releasing memory (87)
                    1> basePacket.cpp
                    1>c1xx : fatal error C1060: compiler is out of heap space
                    1> Note: non-fatal system error releasing memory (87)
                    1> tcpConnectionList.cpp
                    1>c1xx : fatal error C1060: compiler is out of heap space
                    1> Note: non-fatal system error releasing memory (87)
                    1> tcp_server.cpp
                    1>c1xx : fatal error C1060: compiler is out of heap space
                    1> Note: non-fatal system error releasing memory (87)
                    1> NotifycationThreads.cpp
                    1>c1xx : fatal error C1060: compiler is out of heap space
                    1> Note: non-fatal system error releasing memory (87)
                    Сообщение отредактировано: progman -
                      progman, судя по всему баг VC. Попробуй накати все обновления.
                        Цитата shm @
                        progman, судя по всему баг VC. Попробуй накати все обновления.

                        уже. MSVC 2013 Update 4 требуется.
                        обновил. Бага исчезла но все равно падает буст когда стоплю.
                        вот код:
                        ExpandedWrap disabled
                          void CCompletitionPort::closeServer()
                          {
                              io_service.stop();
                              ::WaitForMultipleObjects( m_threadsEvents.size(), &m_threadsEvents[ 0 ], TRUE, INFINITE);
                          }

                        Логика простая - в каждом потоке создаю эвент который дергаю когда поток заканчивает работу.
                        после остановки сервиса жду когда все потоки закончатся.
                        Но падает все где то в недрах буста (
                        ни один поток не заканчивается.

                        поэтому сейчас вот такой вот криворукое решение:
                        ExpandedWrap disabled
                          void CCompletitionPort::closeServer()
                          {
                              exit(0);
                          }

                        :fool:
                          Цитата progman @
                          ::WaitForMultipleObjects( m_threadsEvents.size(), &m_threadsEvents[ 0 ], TRUE, INFINITE);

                          wtf? Если ты используешь буст, то там у объекта thread есть метот join для этих целей.

                          Добавлено
                          Цитата progman @
                          Но падает все где то в недрах буста (

                          Падает как? Буст кидает эксепшен? И где конкретно падает, стек вызовов-то хоть есть?
                          Сообщение отредактировано: shm -
                            Цитата shm @
                            Падает как? Буст кидает эксепшен? И где конкретно падает, стек вызовов-то хоть есть?

                            да эксепшен
                            Цитата
                            Unhandled exception at 0x00089DA6 in servervisuald.exe: 0xC0000005: Access violation reading location 0x08B8F7B0.


                            вот стек:
                            Цитата
                            > servervisuald.exe!boost::asio::basic_io_object<boost::asio::socket_acceptor_service<boost::asio::ip::tcp>,1>::get_service() Line 209 C++
                            servervisuald.exe!boost::asio::basic_socket_acceptor<boost::asio::ip::tcp,boost::asio::socket_acceptor_service<boost::asio::ip::tcp> >::async_accept<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp>,boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > > >(boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> > & peer, boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > > && handler, void * __formal) Line 1019 C++
                            servervisuald.exe!network::server::accept(int id, const boost::system::error_code & err) Line 39 C++
                            servervisuald.exe!network::server::handle_accept(network::server * srv, int id, const boost::system::error_code & err) Line 29 C++
                            servervisuald.exe!boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> >::operator()<void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::rrlist1<boost::system::error_code const &> >(boost::_bi::type<void> __formal, void (network::server *, int, const boost::system::error_code &) * & f, boost::_bi::rrlist1<boost::system::error_code const &> & a, int __formal) Line 398 C++
                            servervisuald.exe!boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > >::operator()<boost::system::error_code const &>(const boost::system::error_code & a1) Line 1235 C++
                            servervisuald.exe!boost::asio::detail::binder1<boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > >,boost::system::error_code>::operator()() Line 48 C++
                            servervisuald.exe!boost::asio::asio_handler_invoke<boost::asio::detail::binder1<boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > >,boost::system::error_code> >(boost::asio::detail::binder1<boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > >,boost::system::error_code> & function, ...) Line 70 C++
                            servervisuald.exe!boost_asio_handler_invoke_helpers::invoke<boost::asio::detail::binder1<boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > >,boost::system::error_code>,boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > > >(boost::asio::detail::binder1<boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > >,boost::system::error_code> & function, boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > > & context) Line 37 C++
                            servervisuald.exe!boost::asio::detail::win_iocp_socket_accept_op<boost::asio::basic_socket<boost::asio::ip::tcp,boost::asio::stream_socket_service<boost::asio::ip::tcp> >,boost::asio::ip::tcp,boost::_bi::bind_t<void,void (__cdecl*)(network::server *,int,boost::system::error_code const &),boost::_bi::list3<boost::_bi::value<network::server *>,boost::_bi::value<int>,boost::arg<1> > > >::do_complete(boost::asio::detail::win_iocp_io_service * owner, boost::asio::detail::win_iocp_operation * base, const boost::system::error_code & result_ec, unsigned int __formal) Line 142 C++
                            servervisuald.exe!boost::asio::detail::win_iocp_operation::complete(boost::asio::detail::win_iocp_io_service & owner, const boost::system::error_code & ec, unsigned int bytes_transferred) Line 46 C++
                            servervisuald.exe!boost::asio::detail::win_iocp_io_service::do_one(bool block, boost::system::error_code & ec) Line 406 C++
                            servervisuald.exe!boost::asio::detail::win_iocp_io_service::run(boost::system::error_code & ec) Line 164 C++
                            servervisuald.exe!boost::asio::io_service::run() Line 59 C++
                            servervisuald.exe!network::workerThread::workingThread() Line 59 C++


                            Добавлено
                            Цитата shm @
                            wtf? Если ты используешь буст, то там у объекта thread есть метот join для этих целей.

                            ну а как я еще в другом потоке узнаю что все рабочие потоки закончились - имхо только через в каждом потоке SetEvent + WaitForMultipleObjects
                            я же говорю буст я практически не знаю. А усиленно разбираться нету времени (

                            Цитата Oleg2004 @
                            Пару слов - как впечатление...Все думаю тоже скачать и попробовать любимую игру в новом виде...Кстати у вас стимовский вариант?

                            не знаю. На стиме купил но играть некогда.
                              Цитата progman @
                              ну а как я еще в другом потоке узнаю что все рабочие потоки закончились - имхо только через в каждом потоке SetEvent + WaitForMultipleObjects

                              ExpandedWrap disabled
                                io_service.stop();
                                for(auto th : ThreadList)
                                {
                                   th->join();
                                   delete th;
                                }

                              ???

                              Добавлено
                              Цитата progman @
                              servervisuald.exe!network::server::accept(int id, const boost::system::error_code & err) Line 39 C++
                              servervisuald.exe!network::server::handle_accept(network::server * srv, int id, const boost::system::error_code & err) Line 29 C++

                              твое? что там понаписано?

                              Добавлено
                              Складывается впечатление, что завершается accept с ошибкой и ты ее некорректно обрабатываешь. Хотя может я и ошибаюсь, так сложно сказать.
                              Сообщение отредактировано: shm -
                                вот полный код всей сетевой части:
                                ExpandedWrap disabled
                                  void    workerThread::workingThread( )
                                  {
                                      mWorkerThread = this;
                                   
                                      try
                                      {
                                          server s( m_dbpool, io_service, m_serverport );
                                          
                                          io_service.run();
                                      }
                                   
                                      catch (std::exception& e)
                                      {
                                          std::cerr << "Exception: " << e.what() << "\n";
                                      }
                                   
                                      ::SetEvent( m_closeThreadEvent );
                                   
                                      return;
                                  }


                                ExpandedWrap disabled
                                      server::server(  dbPool&    dbpool, boost::asio::io_service& io_service, short port)
                                          : m_acceptor( io_service, tcp::endpoint( tcp::v4( ), port ) )
                                          , m_socket( io_service )
                                          , m_dbpool( dbpool )
                                      {
                                          m_acceptor.async_accept( m_socket, boost::bind( handle_accept, this, 0, _1 ) );
                                      }
                                   
                                  server::~server()
                                  {
                                      
                                  }
                                   
                                  void server::handle_accept( server* srv, int id, const boost::system::error_code & err )
                                  {
                                      srv->accept( id, err );
                                  }
                                   
                                  void server::accept( int id, const boost::system::error_code & err )
                                  {
                                      if (!err)
                                      {
                                          std::make_shared<connection>( m_dbpool, std::move( m_socket ) )->accept();
                                      }
                                   
                                      m_acceptor.async_accept( m_socket, boost::bind( handle_accept, this, 0, _1 ) );
                                  }


                                ExpandedWrap disabled
                                  const int CLIENT_TIMEOUT = 3600;
                                   
                                      connection::connection( dbPool& dbpool, tcp::socket socket ) :  m_socket(std::move(socket))
                                          , m_dbpool(dbpool)
                                      {
                                          m_pClient       = NULL;
                                          m_inactivetime  = 0;
                                      }
                                   
                                      connection::~connection()
                                      {
                                          //m_pClient will be destroy inside
                                          if (_S(net::ClientList) )
                                              _S(net::ClientList)->remove(this);
                                      }
                                   
                                      void connection::update(float dt)
                                      {
                                          m_inactivetime += dt;
                                   
                                          if (m_inactivetime >= CLIENT_TIMEOUT)
                                              closeSocket();
                                      }
                                   
                                      void connection::closeSocket()
                                      {
                                          m_socket.close();
                                      }
                                   
                                      HRESULT connection::send( char* buffer, DWORD length )
                                      {
                                          m_inactivetime = 0;
                                   
                                          char* sendbuffer = new char[length + header_length];
                                          memcpy( &sendbuffer[ 0 ], &length, header_length);
                                          memcpy( &sendbuffer[ header_length ], buffer, length );
                                   
                                          boost::asio::async_write( m_socket, boost::asio::buffer( sendbuffer, length + header_length ),
                                              std::bind( &connection::handle_write, shared_from_this(), sendbuffer, std::placeholders::_1, std::placeholders::_2 ) );
                                              
                                          return S_OK;
                                      }
                                   
                                      HRESULT connection::sendPolicy()
                                      {
                                          const char mCrossDomainPolicy[] = "<?xml version=\"1.0\"?>\r\n<!DOCTYPE cross-domain-policy SYSTEM \"/xml/dtds/cross-domain-policy.dtd\">\r\n<cross-domain-policy>\r\n<allow-access-from domain=\"*\" to-ports=\"1-31111\" />\r\n</cross-domain-policy>";
                                          const int length = strlen(mCrossDomainPolicy);
                                   
                                          char* sendbuffer = new char[ length ];
                                          memcpy( &sendbuffer[0], mCrossDomainPolicy, length );
                                   
                                          boost::asio::async_write(m_socket, boost::asio::buffer( sendbuffer, length ),
                                              std::bind(&connection::handle_write, shared_from_this(), sendbuffer, std::placeholders::_1, std::placeholders::_2));
                                   
                                          return S_OK;
                                      }
                                   
                                      void connection::handle_write(char* buffer, const boost::system::error_code& a_error, std::size_t a_size)
                                      {
                                          delete[] buffer;
                                      }
                                   
                                      void connection::accept()
                                      {
                                          m_inactivetime = 0;
                                   
                                          m_pClient = new Client( this, m_dbpool.getDataBase(dbPool::system), m_dbpool.getDataBase(dbPool::logi), m_dbpool.getDataBase(dbPool::tickets ) );
                                          
                                          m_pClient->onConnect( m_socket.remote_endpoint().address().to_v4().to_ulong() );
                                   
                                          _S(net::ClientList)->push( this );
                                   
                                          do_read_header( );
                                      }
                                   
                                      void connection::do_read_header()
                                      {
                                          m_inactivetime = 0;
                                   
                                          auto self( shared_from_this( ) );
                                   
                                          m_socket.async_read_some(boost::asio::buffer(m_recvbuffer, header_length), [this, self](boost::system::error_code ec, std::size_t length)
                                          {
                                              if( !ec )
                                              {
                                                  int bodylength = ((int*)m_recvbuffer)[0];
                                                  
                                                  if (bodylength > 0 && bodylength < max_length)
                                                  {
                                                      do_read_body( bodylength );
                                                  }
                                                  else
                                                  {
                                                      const char mPolicyFileRequest[] = "<policy-file-request/>";
                                                      if ( 'lop<' == bodylength )
                                                      {
                                                          do_read_body( static_cast< unsigned int > (strlen( mPolicyFileRequest ) - PROTOCOL_HEADER_SIZE) );
                                                      }
                                                      else
                                                          m_socket.close();
                                                  }
                                   
                                              }
                                          } );
                                      }
                                   
                                      
                                      void connection::do_read_body( int datalength )
                                      {
                                          m_inactivetime = 0;
                                   
                                          auto self( shared_from_this( ) );
                                          
                                          m_socket.async_read_some(boost::asio::buffer( m_recvbuffer, datalength ), [this, self](boost::system::error_code ec, std::size_t length)
                                          {
                                              if( !ec )
                                              {
                                                  if ( 18 == length && checkPoliciFileRequest( m_recvbuffer ) )
                                                  {
                                                      
                                                      this->sendPolicy();
                                   
                                                      return;
                                                  }
                                                  else
                                                  {                  
                                                      
                                                      
                                                      HRESULT hr = m_pClient->onReceiveBlock((unsigned char*)m_recvbuffer, length);
                                   
                                   
                                                      if (S_OK == hr)
                                                      {
                                                          do_read_header();
                                                      }
                                   
                                                      if (S_DISCONNECT == hr)
                                                          m_socket.close();
                                                  }
                                              }
                                          } );
                                   
                                      }
                                  Цитата progman @
                                  void server::accept( int id, const boost::system::error_code & err )
                                  {
                                  if (!err)
                                  {
                                  std::make_shared<connection>( m_dbpool, std::move( m_socket ) )->accept();
                                  }

                                  m_acceptor.async_accept( m_socket, boost::bind( handle_accept, this, 0, _1 ) );
                                  }

                                  Скорее всего бага тут. Попробуй добавь для отладки проверку флага завершения:
                                  ExpandedWrap disabled
                                    void server::accept( int id, const boost::system::error_code & err )
                                    {
                                        if(TerminateFlag)
                                            return;
                                        if (!err)
                                        {
                                            std::make_shared<connection>( m_dbpool, std::move( m_socket ) )->accept();
                                        }
                                     
                                        m_acceptor.async_accept( m_socket, boost::bind( handle_accept, this, 0, _1 ) );
                                    }
                                    ...
                                    TerminateFlag = false;
                                    io_service.stop();
                                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                                  0 пользователей:
                                  Страницы: (3) 1 [2] 3  все


                                  Рейтинг@Mail.ru
                                  [ Script execution time: 0,0605 ]   [ 17 queries used ]   [ Generated: 19.04.24, 04:41 GMT ]