Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> помогите найти ошибку в коде 
V
    Опции темы
SenkraD
Дата 16.9.2009, 10:48 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 2
Всего: 23



Код
#include <iostream>
#include <sstream>

#include "MessagesObjects.hpp"              // Need for MsgType

#include <boost/archive/text_iarchive.hpp>  // Serialization
#include <boost/archive/text_oarchive.hpp>  // Serialization
#include <boost/serialization/vector.hpp>
#include <boost/bind.hpp>                   // Serialization
#include <boost/tuple/tuple.hpp>            // Serialization


//--------------------------------------------------------------------------------------------------
namespace Serialization
{
    //--------------------------------------------------------------------------------------------------
    // Each message sent using this class consists of:
    //    - an 8-byte header containing the length of the serialized data.
    //    - the serialized data.
    //
    class SerializedCommunication
    {
    private: // Constants
        enum
        {
              kHeaderLength = 8 // The size of a fixed length header.
        };

    public:  // Interface
        SerializedCommunication(boost::asio::ip::tcp::socket& socket)
            : m_isTagProbed(false)
            , m_socket(socket)
        {
        }
    
        template<typename T, typename Handler>
        void asynWrite(MsgType const tag, T const& data, Handler handler)
        {
            packData(tag, data, handler);

            std::vector<boost::asio::const_buffer> buffers;
            buffers.push_back(boost::asio::buffer(m_outboundHeader));
            buffers.push_back(boost::asio::buffer(m_outboundData));
            boost::asio::async_write(m_socket, buffers, handler);
        }

        template<typename T, typename Handler>
        void write(MsgType const tag, T const& data, Handler handler)
        {
            packData(tag, data, handler);

            std::vector<boost::asio::const_buffer> buffers;
            buffers.push_back(boost::asio::buffer(m_outboundHeader));
            buffers.push_back(boost::asio::buffer(m_outboundData));
            try
            {
                boost::asio::write(m_socket, buffers);
            }
            catch (boost::system::system_error& ex)
            {
                handler(ex.code());
            }
        }

        template<typename T, typename Handler>
        void asyncRead(T& data, Handler handler)
        {
            typedef void (SerializedCommunication::*Function)(const boost::system::error_code&, T&, boost::tuple<Handler>);

            Function func = &SerializedCommunication::handleReadHeader<T, Handler>;
            boost::asio::async_read(
                m_socket, boost::asio::buffer(m_inboundHeader),
                boost::bind(func, this, boost::asio::placeholders::error, boost::ref(data), boost::make_tuple(handler))
            );
        }

        template<typename T, typename Handler>
        void read(T& data, Handler handler)
        {
            boost::system::error_code error;
            boost::asio::read(m_socket, boost::asio::buffer(m_inboundHeader), boost::asio::transfer_all(), error);
            if (error)
            {
                handler(error);
                return;
            }

            unpackDataHeader();
            if (m_inboundDataTag == Serialization::kMessageTypePing)
            {
                std::cout << "GOT ";
                boost::asio::read(m_socket, boost::asio::buffer(m_inboundData));
                std::cout << "A PING MESSAGE\n";
                read(data, handler);
            }
            else
            {
                boost::asio::read(m_socket, boost::asio::buffer(m_inboundData), boost::asio::transfer_all(), error);
                //handleReadData(error, boost::ref(data), boost::make_tuple(handler));
            }
        }

    private: // Details
        template<typename T, typename Handler>
        void packData(MsgType const tag, T const& data, Handler handler) 
        {
            // Serialize the data first so we know how large it is.
            std::ostringstream archiveStream;
            boost::archive::text_oarchive archive(archiveStream);
            archive << data;
            m_outboundData = archiveStream.str();

            // Format the header.
            //  lenght . ' ' .tag
            std::ostringstream headerStream, headerMsg;
            headerMsg << m_outboundData.size() << ' ' << tag;
            headerStream << std::setw(kHeaderLength) << headerMsg.str();

            if (!headerStream)
            {
                boost::system::error_code error(boost::asio::error::invalid_argument);
                m_socket.io_service().post(boost::bind(handler, error));
                std::cout << " Error in sending\n";
                return;
            }
            m_outboundHeader = headerStream.str();
        }

        void unpackDataHeader(void) 
        {
            std::istringstream is(std::string(m_inboundHeader, kHeaderLength));
            std::size_t inboundDataSize = 0;

            if (!(is >> inboundDataSize >> m_inboundDataTag))
            {
                std::cout << "Fatal error deserializing message header ";
                std::cout << is.str() << "\n";
                exit(-1);  // TODO: FIXME
            }    
            m_inboundData.resize(inboundDataSize);
        }

        template<typename T, typename Handler>
        void handleReadHeader(boost::system::error_code const& error, T& data, boost::tuple<Handler> handler)
        {
            if (error)
            {
                boost::get<0>(handler)(error);
            }
            else
            {
                unpackDataHeader();
                if (m_inboundDataTag == Serialization::kMessageTypePing)
                {
                    std::cout << "GOT ";
                    boost::asio::read(m_socket, boost::asio::buffer(m_inboundData));
                    std::cout << "A PING MESSAGE\n";
                    handleReadHeader(error, data, handler);
                }
                else
                {
                    typedef void (SerializedCommunication::*Function)(boost::system::error_code const&, T&, boost::tuple<Handler>);

                    Function readHandler = &SerializedCommunication::handleReadData<T, Handler>;
                    boost::asio::async_read(
                        m_socket, boost::asio::buffer(m_inboundData),
                        boost::bind(readHandler, this, boost::asio::placeholders::error, boost::ref(data), handler)
                    );
                }
            }
        }

        template<typename T, typename Handler>
        void handleReadData(boost::system::error_code const& error, T& data, boost::tuple<Handler> handler)
        {
            if (error)
            {
                boost::get<0>(handler)(error);
            }
            else
            {
                try
                {
                    std::string archiveData(&m_inboundData[0], m_inboundData.size());
                    std::istringstream archiveStream(archiveData);
                    boost::archive::text_iarchive archive(archiveStream);
                    archive >> data;
                }
                catch (std::exception& )
                {
                    boost::system::error_code error(boost::asio::error::invalid_argument);
                    boost::get<0>(handler)(error);
                    std::cout << "Error deserializing\n";
                    return;
                }
                boost::get<0>(handler)(error);
            }
        }

    private: // Fields
        std::string                     m_outboundHeader;               // Holds an outbound header
        std::string                     m_outboundData;                 // Holds the outbound data
        char                            m_inboundHeader[kHeaderLength]; // Holds an inbound header
        bool                            m_isTagProbed;                  // True When the tag has been already probed
        std::vector<char>               m_inboundData;                  // Holds the inbound data
        MsgType                         m_inboundDataTag;               // Hold the inbound data tag
        boost::asio::ip::tcp::socket&   m_socket;                       // Socket for the connection (passed by reference here)

    }; // class SerializedCommunication
} // namespace Serialization
 если вызываю asyncRead всё ок, а если с теми же параметрами вызываю read, то получаю ошибку компиляции



--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
bsa
Дата 16.9.2009, 14:34 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



и что ты ждешь? где сообщения об ошибках?
PM   Вверх
SenkraD
Дата 16.9.2009, 16:30 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 2
Всего: 23



Да там ещё в функции read строчка вызова handleReadData не закоментирована!!!
Ошибки:1>g:\devlibs\boost\installs\boost_1_39_0\include\boost-1_39\boost\archive\detail\iserializer.hpp(560) : error C2664: 'boost::archive::load_wrapper' : cannot convert parameter 3 from 'boost::serialization::is_wrapper<T>' to 'boost::mpl::true_'
1>        with
1>        [
1>            T=boost::reference_wrapper<Serialization::SystemMessage>
1>        ]
1>        No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called
1>        g:\devlibs\boost\installs\boost_1_39_0\include\boost-1_39\boost\archive\detail\common_iarchive.hpp(59) : see reference to function template instantiation 'void boost::archive::load<Archive,const T>(Archive &,const T &)' being compiled
1>        with
1>        [
1>            Archive=boost::archive::text_iarchive,
1>            T=const boost::reference_wrapper<Serialization::SystemMessage>
1>        ]
1>        g:\devlibs\boost\installs\boost_1_39_0\include\boost-1_39\boost\archive\basic_text_iarchive.hpp(62) : see reference to function template instantiation 'void boost::archive::detail::common_iarchive<Archive>::load_override<T>(T &,int)' being compiled
1>        with
1>        [
1>            Archive=boost::archive::text_iarchive,
1>            T=const boost::reference_wrapper<Serialization::SystemMessage>
1>        ]
1>        g:\devlibs\boost\installs\boost_1_39_0\include\boost-1_39\boost\archive\text_iarchive.hpp(65) : see reference to function template instantiation 'void boost::archive::basic_text_iarchive<Archive>::load_override<T>(T &,int)' being compiled
1>        with
1>        [
1>            Archive=boost::archive::text_iarchive,
1>            T=const boost::reference_wrapper<Serialization::SystemMessage>
1>        ]
1>        g:\devlibs\boost\installs\boost_1_39_0\include\boost-1_39\boost\archive\detail\interface_iarchive.hpp(61) : see reference to function template instantiation 'void boost::archive::text_iarchive_impl<Archive>::load_override<T>(T &,int)' being compiled
1>        with
1>        [
1>            Archive=boost::archive::text_iarchive,
1>            T=const boost::reference_wrapper<Serialization::SystemMessage>
1>        ]
1>        g:\projects\aspb\battle\dcs\common\serializedcomoperations.hpp(205) : see reference to function template instantiation 'Archive &boost::archive::detail::interface_iarchive<Archive>::operator >><T>(T &)' being compiled
1>        with
1>        [
1>            Archive=boost::archive::text_iarchive,
1>            T=const boost::reference_wrapper<Serialization::SystemMessage>
1>        ]
1>        g:\projects\aspb\battle\dcs\common\serializedcomoperations.hpp(117) : see reference to function template instantiation 'void Serialization::SerializedCommunication::handleReadData<const boost::reference_wrapper<T>,Handler>(const boost::system::error_code &,const boost::reference_wrapper<T> &,boost::tuples::tuple<T0>)' being compiled
1>        with
1>        [
1>            T=Serialization::SystemMessage,
1>            Handler=boost::_bi::bind_t<void,boost::_mfi::mf1<void,Network::Client,const boost::system::error_code &>,boost::_bi::list2<boost::_bi::value<Network::Client *>,boost::arg<1>>>,
1>            T0=boost::_bi::bind_t<void,boost::_mfi::mf1<void,Network::Client,const boost::system::error_code &>,boost::_bi::list2<boost::_bi::value<Network::Client *>,boost::arg<1>>>
1>        ]
1>        g:\projects\aspb\battle\dcs\dcsclient\dcsclient.cpp(111) : see reference to function template instantiation 'void Serialization::SerializedCommunication::read<Serialization::SystemMessage,boost::_bi::bind_t<R,F,L>>(T &,Handler)' being compiled
1>        with
1>        [
1>            R=void,
1>            F=boost::_mfi::mf1<void,Network::Client,const boost::system::error_code &>,
1>            L=boost::_bi::list2<boost::_bi::value<Network::Client *>,boost::arg<1>>,
1>            T=Serialization::SystemMessage,
1>            Handler=boost::_bi::bind_t<void,boost::_mfi::mf1<void,Network::Client,const boost::system::error_code &>,boost::_bi::list2<boost::_bi::value<Network::Client *>,boost::arg<1>>>
1>        ]


Это сообщение отредактировал(а) SenkraD - 16.9.2009, 16:34


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
bsa
Дата 17.9.2009, 22:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



Посмотри внимательно документацию. Возможно, у read и async_read кардинально разные параметры должны быть.
PM   Вверх
SenkraD
Дата 18.9.2009, 08:02 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 2
Всего: 23



как раз с этими функциями проблеммы нет, как я понял по ошибке компилятора
матерится сериализация, но никак не пойму почему - параметры за исключением
обработчиков ошибок одиниковые



--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
Anikmar
Дата 18.9.2009, 10:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Завсегдатай
Сообщений: 2513
Регистрация: 26.11.2006
Где: Санкт-Петербург

Репутация: 9
Всего: 59



Слишком много кода.
Локализуйте ошибку - проще найти будет. Оставьте в коде пару значимых строк, мне кажется быстрее будет.
PM MAIL ICQ   Вверх
SenkraD
Дата 18.9.2009, 11:18 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 2
Всего: 23



Anikmar,  я не могу его выделить!
Код
template<typename T, typename Handler>
 void handleReadData(boost::system::error_code const& error, T& data, boost::tuple<Handler> handler)
 {
     if (error)
     {
          boost::get<0>(handler)(error);
     }
     else
     {
           try
           {
                std::string archiveData(&m_inboundData[0], m_inboundData.size());
                std::istringstream archiveStream(archiveData);
                boost::archive::text_iarchive archive(archiveStream);
                archive >> data; // вот если это закоментить, то вызов функции read скомпилится без ошибок
           }
           catch (std::exception& )
           {
               //..
           }
           boost::get<0>(handler)(error);
     }
}

// client code
MsgType msg;
SerializedCommunication& comm = ...;
comm.asyncRead(msg, someErrorHandler); // OK
comm.read(msg, someErrorHandler); // Fail
comm.asyncWrite(tag, msg, someErrorHandler); // OK
comm.write(tag, msg, someErrorHandler); // OK
Итого мы имем:
  • сериализируем мы нормально, как в asyncWrite, так и в write
  • мы десериалезируем в asynRead, но в упор отказываемся это делать в read


Добавлено через 12 минут и 24 секунды
вопрос закрыт - это всё злой копипаст :-(
Код
template<typename T, typename Handler>
        void read(T& data, Handler handler)
        {
            boost::system::error_code error;
            boost::asio::read(m_socket, boost::asio::buffer(m_inboundHeader), boost::asio::transfer_all(), error);
            if (error)
            {
                handler(error);
                return;
            }

            unpackDataHeader();
            if (m_inboundDataTag == Serialization::kMessageTypePing)
            {
                std::cout << "GOT ";
                boost::asio::read(m_socket, boost::asio::buffer(m_inboundData));
                std::cout << "A PING MESSAGE\n";
                read(data, handler);
            }
            else
            {
                boost::asio::read(m_socket, boost::asio::buffer(m_inboundData), boost::asio::transfer_all(), error);
                handleReadData(error, data/*boost::ref(data) - было это*/, boost::make_tuple(handler));
            }
        }




--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
SenkraD
Дата 18.9.2009, 11:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 933
Регистрация: 3.2.2006
Где: Украина::Киев

Репутация: 2
Всего: 23



всё тема закрыта


--------------------
 Имеющий язык - да не убоится спросить! 
user posted image
PM MAIL ICQ   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0534 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.