crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

 
Ответить в данную темуНачать новую тему
> Свой протокол, Создание сетевого протокола для своего приложения
Румата Эсторский
  опции профиля:
сообщение 7.2.2011, 17:26
Сообщение #1


Студент
*

Группа: Новичок
Сообщений: 11
Регистрация: 2.2.2011
Пользователь №: 2388

Спасибо сказали: 0 раз(а)




Репутация:   0  


Здравствуйте, уважаемые разработчики.

Подскажите пожалуйста где можно почитать инфу о создании своего протокола для взаимодействия клиент-серверного приложения. Клиент на Qt, сервер на Java.
Требования к протоколу - компактность и большая скорость обработки пакетов на сервере, так что XML не подходит.

Может быть уже есть какие-то шаблонные классы для решения этой задачи. Может быть есть литература, примеры.

И еще скажите - правильно ли сделать такую схему для обработки протокола:
есть базовый класс Message - основные функции по сборке/разборке сообщения, доступ к полям сообщения и т.д.
а дальше для каждого типа сообщения свой класс унаследованный от Message.
Типов сообщений пока около 100, но дальше их будет больше. Скажите, верно ли иметь в программе такую кучу классов для сетевой подсистемы?

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
kuzulis
  опции профиля:
сообщение 7.2.2011, 17:49
Сообщение #2


Активный участник
***

Группа: Участник
Сообщений: 393
Регистрация: 29.6.2009
Пользователь №: 862

Спасибо сказали: 36 раз(а)




Репутация:   7  


А JSON не подходит?
Или вам необходим бинарный протокол?
И что за данные в сообщениях будут передаваться?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Румата Эсторский
  опции профиля:
сообщение 7.2.2011, 18:23
Сообщение #3


Студент
*

Группа: Новичок
Сообщений: 11
Регистрация: 2.2.2011
Пользователь №: 2388

Спасибо сказали: 0 раз(а)




Репутация:   0  


Цитата(kuzulis @ 7.2.2011, 17:49) *
А JSON не подходит?
Или вам необходим бинарный протокол?
И что за данные в сообщениях будут передаваться?


Данные - ходы в партиях, списки (игроков, турниров и прочее списки),
бинарные тоже - фотографии, хотя может фотографии заправшивать по HTTP?

я не думал насчет JSON.
Насколько быстро разбирается/собирается JSON?
Какие компонеты для С++ Qt клиента (и для Java сервера) вы порекомендовали бы для работы с JSON?
JSON снимает вопрос насчет наследников от Message или все-таки стоит выстроить такую иерархию независимо от протокола передачи?

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
crashsp
  опции профиля:
сообщение 8.2.2011, 19:38
Сообщение #4


Студент
*

Группа: Участник
Сообщений: 56
Регистрация: 23.10.2010
Пользователь №: 2144

Спасибо сказали: 8 раз(а)




Репутация:   546  


Цитата(Румата Эсторский @ 7.2.2011, 18:23) *
Цитата(kuzulis @ 7.2.2011, 17:49) *
А JSON не подходит?
Или вам необходим бинарный протокол?
И что за данные в сообщениях будут передаваться?


Данные - ходы в партиях, списки (игроков, турниров и прочее списки),
бинарные тоже - фотографии, хотя может фотографии заправшивать по HTTP?

я не думал насчет JSON.
Насколько быстро разбирается/собирается JSON?
Какие компонеты для С++ Qt клиента (и для Java сервера) вы порекомендовали бы для работы с JSON?
JSON снимает вопрос насчет наследников от Message или все-таки стоит выстроить такую иерархию независимо от протокола передачи?


Ну вот тут нашелся класс для парсения json меня как то раз спас не знаю поможет может чем, а вообще есть отдельная библиотка для работы с json вот только под себя я так и не смог ее адаптировать вот http://qjson.sourceforge.net/

А вот класс:

файл h.

Раскрывающийся текст

/**
* \file json.h
*
* \author Eeli Reilin <eeli@nilier.org>,
*         Mikko Ahonen <mikko.j.ahonen@jyu.fi>
* \version 0.1
* \date 8/25/2010
*/

#ifndef JSON_H
#define JSON_H

#include <QVariant>
#include <QString>

/**
* \enum JsonToken
*/
enum JsonToken
{
    JsonTokenNone = 0,
    JsonTokenCurlyOpen = 1,
    JsonTokenCurlyClose = 2,
    JsonTokenSquaredOpen = 3,
    JsonTokenSquaredClose = 4,
    JsonTokenColon = 5,
    JsonTokenComma = 6,
    JsonTokenString = 7,
    JsonTokenNumber = 8,
    JsonTokenTrue = 9,
    JsonTokenFalse = 10,
    JsonTokenNull = 11
};

/**
* \class Json
* \brief A JSON data parser
*
* Json parses a JSON data into a QVariant hierarchy.
*/
class Json
{
    public:
        /**
         * Parse a JSON string
         *
         * \param json The JSON data
         */
        static QVariant parse(const QString &json);

        /**
         * Parse a JSON string
         *
         * \param json The JSON data
         * \param success The success of the parsing
         */
        static QVariant parse(const QString &json, bool &success);

    private:
        /**
         * Parses a value starting from index
         *
         * \param json The JSON data
         * \param index The start index
         * \param success The success of the parse process
         *
         * \return QVariant The parsed value
         */
        static QVariant parseValue(const QString &json, int &index,
                                   bool &success);

        /**
         * Parses an object starting from index
         *
         * \param json The JSON data
         * \param index The start index
         * \param success The success of the object parse
         *
         * \return QVariant The parsed object map
         */
        static QVariant parseObject(const QString &json, int &index,
                                       bool &success);

        /**
         * Parses an array starting from index
         *
         * \param json The JSON data
         * \param index The starting index
         * \param success The success of the array parse
         *
         * \return QVariant The parsed variant array
         */
        static QVariant parseArray(const QString &json, int &index,
                                       bool &success);

        /**
         * Parses a string starting from index
         *
         * \param json The JSON data
         * \param index The starting index
         * \param success The success of the string parse
         *
         * \return QVariant The parsed string
         */
        static QVariant parseString(const QString &json, int &index,
                                    bool &success);

        /**
         * Parses a number starting from index
         *
         * \param json The JSON data
         * \param index The starting index
         *
         * \return QVariant The parsed number
         */
        static QVariant parseNumber(const QString &json, int &index);

        /**
         * Get the last index of a number starting from index
         *
         * \param json The JSON data
         * \param index The starting index
         *
         * \return The last index of the number
         */
        static int lastIndexOfNumber(const QString &json, int index);

        /**
         * Skip unwanted whitespace symbols starting from index
         *
         * \param json The JSON data
         * \param index The start index
         */
        static void eatWhitespace(const QString &json, int &index);

        /**
         * Check what token lies ahead
         *
         * \param json The JSON data
         * \param index The starting index
         *
         * \return int The upcoming token
         */
        static int lookAhead(const QString &json, int index);

        /**
         * Get the next JSON token
         *
         * \param json The JSON data
         * \param index The starting index
         *
         * \return int The next JSON token
         */
        static int nextToken(const QString &json, int &index);
};

#endif //JSON_H



а вот cpp.
Раскрывающийся текст

/**
* \file json.h
*
* \author Eeli Reilin <eeli@nilier.org>,
*         Mikko Ahonen <mikko.j.ahonen@jyu.fi>
* \version 0.1
* \date 8/25/2010
*/

#include <QDebug>

#include "json.h"

/**
* parse
*/
QVariant Json::parse(const QString &json)
{
    bool success = true;
    return Json::parse(json, success);
}

/**
* parse
*/
QVariant Json::parse(const QString &json, bool &success)
{
    success = true;

    //Return an empty QVariant if the JSON data is either null or empty
    if(!json.isNull() || !json.isEmpty())
    {
        QString data = json;
        //We'll start from index 0
        int index = 0;

        //Parse the first value
        QVariant value = Json::parseValue(data, index, success);

        //Return the parsed value
        return value;
    }
    else
    {
        //Return the empty QVariant
        return QVariant();
    }
}

/**
* parseValue
*/
QVariant Json::parseValue(const QString &json, int &index, bool &success)
{
    //Determine what kind of data we should parse by
    //checking out the upcoming token
    switch(Json::lookAhead(json, index))
    {
        case JsonTokenString:
            return Json::parseString(json, index, success);
        case JsonTokenNumber:
            return Json::parseNumber(json, index);
        case JsonTokenCurlyOpen:
            return Json::parseObject(json, index, success);
        case JsonTokenSquaredOpen:
            return Json::parseArray(json, index, success);
        case JsonTokenTrue:
            Json::nextToken(json, index);
            return QVariant(true);
        case JsonTokenFalse:
            Json::nextToken(json, index);
            return QVariant(false);
        case JsonTokenNull:
            Json::nextToken(json, index);
            return QVariant();
        case JsonTokenNone:
            break;
    }

    //If there were no tokens, flag the failure and return an empty QVariant
    success = false;
    return QVariant();
}

/**
* parseObject
*/
QVariant Json::parseObject(const QString &json, int &index, bool &success)
{
    QVariantMap map;
    int token;

    //Get rid of the whitespace and increment index
    Json::nextToken(json, index);

    //Loop through all of the key/value pairs of the object
    bool done = false;
    while(!done)
    {
        //Get the upcoming token
        token = Json::lookAhead(json, index);

        if(token == JsonTokenNone)
        {
             success = false;
             return QVariantMap();
        }
        else if(token == JsonTokenComma)
        {
            Json::nextToken(json, index);
        }
        else if(token == JsonTokenCurlyClose)
        {
            Json::nextToken(json, index);
            return map;
        }
        else
        {
            //Parse the key/value pair's name
            QString name = Json::parseString(json, index, success).toString();

            if(!success)
            {
                return QVariantMap();
            }

            //Get the next token
            token = Json::nextToken(json, index);

            //If the next token is not a colon, flag the failure
            //return an empty QVariant
            if(token != JsonTokenColon)
            {
                success = false;
                return QVariant(QVariantMap());
            }

            //Parse the key/value pair's value
            QVariant value = Json::parseValue(json, index, success);

            if(!success)
            {
                return QVariantMap();
            }

            //Assign the value to the key in the map
            map[name] = value;
        }
    }

    //Return the map successfully
    return QVariant(map);
}

/**
* parseArray
*/
QVariant Json::parseArray(const QString &json, int &index, bool &success)
{
    QVariantList list;

    Json::nextToken(json, index);

    bool done = false;
    while(!done)
    {
        int token = Json::lookAhead(json, index);

                if(token == JsonTokenNone)
        {
            success = false;
            return QVariantList();
        }
        else if(token == JsonTokenComma)
        {
            Json::nextToken(json, index);
        }
        else if(token == JsonTokenSquaredClose)
        {
            Json::nextToken(json, index);
            break;
        }
        else
        {
            QVariant value = Json::parseValue(json, index, success);

            if(!success)
            {
                return QVariantList();
            }

            list.push_back(value);
                          }
            }

    return QVariant(list);
}

/**
* parseString
*/
QVariant Json::parseString(const QString &json, int &index, bool &success)
{
    QString s;
    QChar c;

    Json::eatWhitespace(json, index);

    c = json[index++];

    bool complete = false;
    while(!complete)
    {
        if(index == json.size())
        {
            break;
        }

        c = json[index++];

        if(c == '\"')
        {
            complete = true;
            break;
        }
        else if(c == '\\')
        {
            if(index == json.size())
            {
                break;
            }

            c = json[index++];

            if(c == '\"')
            {
                s.append('\"');
            }
            else if(c == '\\')
            {
                s.append('\\');
            }
            else if(c == '/')
            {
                s.append('/');
            }
            else if(c == 'b')
            {
                s.append('\b');
            }
            else if(c == 'f')
            {
                s.append('\f');
            }
            else if(c == 'n')
            {
                s.append('\n');
            }
            else if(c == 'r')
            {
                s.append('\r');
            }
            else if(c == 't')
            {
                s.append('\t');
            }
            else if(c == 'u')
            {
                int remainingLength = json.size() - index;

                if(remainingLength >= 4)
                {
                    QString unicodeStr = json.mid(index, 4);

                    int symbol = unicodeStr.toInt(0, 16);
                    
                    s.append(QChar(symbol));

                    index += 4;
                }
                else
                {
                    break;
                }
            }
        }
        else
        {
            s.append(c);
        }
    }

    if(!complete)
    {
        success = false;
        return QVariant();
    }

    return QVariant(s);
}

/**
* parseNumber
*/
QVariant Json::parseNumber(const QString &json, int &index)
{
    Json::eatWhitespace(json, index);

    int lastIndex = Json::lastIndexOfNumber(json, index);
    int charLength = (lastIndex - index) + 1;
    QString numberStr;

    numberStr = json.mid(index, charLength);
    
    index = lastIndex + 1;

    return QVariant(numberStr);
}

/**
* lastIndexOfNumber
*/
int Json::lastIndexOfNumber(const QString &json, int index)
{
    int lastIndex;

    for(lastIndex = index; lastIndex < json.size(); lastIndex++)
    {
        if(QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1)
        {
            break;
        }
    }

    return lastIndex -1;
}

/**
* eatWhitespace
*/
void Json::eatWhitespace(const QString &json, int &index)
{
    for(; index < json.size(); index++)
    {
        if(QString(" \t\n\r").indexOf(json[index]) == -1)
        {
            break;
        }
    }
}

/**
* lookAhead
*/
int Json::lookAhead(const QString &json, int index)
{
    int saveIndex = index;
    return Json::nextToken(json, saveIndex);
}

/**
* nextToken
*/
int Json::nextToken(const QString &json, int &index)
{
    Json::eatWhitespace(json, index);

    if(index == json.size())
    {
        return JsonTokenNone;
    }

    QChar c = json[index];
    index++;
    switch(c.toAscii())
    {
        case '{': return JsonTokenCurlyOpen;
        case '}': return JsonTokenCurlyClose;
        case '[': return JsonTokenSquaredOpen;
        case ']': return JsonTokenSquaredClose;
        case ',': return JsonTokenComma;
        case '"': return JsonTokenString;
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
        case '-': return JsonTokenNumber;
        case ':': return JsonTokenColon;
    }

    index--;

    int remainingLength = json.size() - index;

    //True
    if(remainingLength >= 4)
    {
        if (json[index] == 't' && json[index + 1] == 'r' &&
            json[index + 2] == 'u' && json[index + 3] == 'e')
        {
            index += 4;
            return JsonTokenTrue;
        }
    }

    //False
    if (remainingLength >= 5)
    {
        if (json[index] == 'f' && json[index + 1] == 'a' &&
            json[index + 2] == 'l' && json[index + 3] == 's' &&
            json[index + 4] == 'e')
        {
            index += 5;
            return JsonTokenFalse;
        }
    }

    //Null
    if (remainingLength >= 4)
    {
        if (json[index] == 'n' && json[index + 1] == 'u' &&
            json[index + 2] == 'l' && json[index + 3] == 'l')
        {
            index += 4;
            return JsonTokenNull;
        }
    }

    return JsonTokenNone;
}


Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Румата Эсторский
  опции профиля:
сообщение 10.2.2011, 1:33
Сообщение #5


Студент
*

Группа: Новичок
Сообщений: 11
Регистрация: 2.2.2011
Пользователь №: 2388

Спасибо сказали: 0 раз(а)




Репутация:   0  


Я вот думаю не воспользоваться ли QHessian http://habrahabr.ru/blogs/cpp/109393/
Он бинарный, то есть компактнее JSON, и на первый взгляд очень удобный.
Как считаете?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
crashsp
  опции профиля:
сообщение 16.2.2011, 14:47
Сообщение #6


Студент
*

Группа: Участник
Сообщений: 56
Регистрация: 23.10.2010
Пользователь №: 2144

Спасибо сказали: 8 раз(а)




Репутация:   546  


Цитата(Румата Эсторский @ 10.2.2011, 2:33) *
Я вот думаю не воспользоваться ли QHessian http://habrahabr.ru/blogs/cpp/109393/
Он бинарный, то есть компактнее JSON, и на первый взгляд очень удобный.
Как считаете?


По моему отличный вариант плюсов много )) да и на первый взгляд реализовано все на уровне... НО я сам вижу ее в первый раз так что если под вашу задачу подходит почему бы нет ??

ПЖЛ не бросайте тему если вдруг на чем то конкретном остановитесь отпишитесь
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


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




RSS Текстовая версия Сейчас: 22.11.2024, 17:16